本系列是一個新的系列,在此系列中,我將和大家共同學習R語言。由於我對R語言的了解也甚少,所以本系列更多以一個學習者的視角來完成。
參考教材:《R語言實戰》第二版(Robert I.Kabacoff),書中所提到的John Cook的優秀博文,關於代碼規范的《來自Google的R語言編碼風格指南》。
Part 1:變量管理
Section 1:創建變量——transform()
為數據框創建新變量,可以使用數據框的$
運算符,如果df$variable
中variable
不屬於原數據框,則會創建一個新的數據框。
mydata <- data.frame(
x1 = c(2, 2, 6, 4),
x2 = c(3, 4, 2, 8)
)
mydata$sumx <- mydata$x1 + mydata$x2
mydata$meanx <- mydata$sumx / 2
使用transform()
函數,能更方便地創建新變量,其用法是:
mydata <- data.frame(
x1 = c(2, 2, 6, 4),
x2 = c(3, 4, 2, 8)
)
mydata <- transform(mydata,
sumx = x1 + x2,
meanx = (x1 + x2)/2)
除此外,transform()
函數也能方便地對數據框執行修改,生成一個修改后的映像。
Section 2:變量的重編碼——within()
變量的重編碼,指的是根據變量的現有值創建新值的過程,如分箱、糾正錯誤值等。
為方便以下內容的示范,使用書中給出的原始數據框:

manager <- c(1, 2, 3, 4, 5)
date <- c("10/24/14", "10/28/14", "10/01/14", "10/12/14", "05/01/14")
country <- c("US", "US", "UK", "UK", "UK")
gender <- c("M", "F", "F", "M", "F")
age <- c(32, 45, 25, 39, 99)
q1 <- c(5, 3, 3, 3, 2)
q2 <- c(4, 5, 5, 3, 2)
q3 <- c(5, 2, 5, 4, 1)
q4 <- c(5, 5, 5, NA, 2)
q5 <- c(5, 5, 2, NA, 1)
leadership <- data.frame(manager, date, country, gender, age,
q1, q2, q3, q4, q5, stringsAsFactors = F)
條件賦值語句可以在條件為TRUE
時,為向量的相應位置執行賦值,其用法為
variable[condition] <- expression # 這里condition是一個條件向量
結合within()
函數,可以方便地為數據框執行重編碼,within()
函數的語法與with()
類似,但with()
只允許方便地調用數據框中的變量,而within()
還允許修改數據框。如,為leadership
數據框中的agecat
執行重編碼:
leadership$age[leadership$age == 99] <- NA # 將異常值編碼為NA
leadership <- within(leadership,{
agecat <- NA
agecat[age > 75] <- "Elder"
agecat[age <= 75 & age >= 55] <- "Middle Aged"
agecat[age < 55] <- "Young"
})
Section 3:變量重命名——names()
對變量名稱不滿意,可以使用fix(df)
函數,交互式地更改變量名稱,也可以使用names()
函數。如
names(leadership)[2] <- "testDate"
names(leadership)[6:10] <- c("item1", "item2", "item3", "item4", "item5")
或使用plyr
包中的rename
函數修改變量名。
leadership <- rename(leadership, c(manager="managerID"))
Part 2:值處理
Section 1:缺失值
缺失值以符號NA
表示,意為Not Available,它是不可比較的(即使是x == NA
也不行,只能用is.na(x)
)。在R語言中,缺失值與Inf
(正無窮)、-Inf
(負無窮)、NaN
(不是一個數,Not a Number)不同,以上是它們的符號。
需要注意,含有缺失值的算術表達式和函數的計算結果也是缺失值。多值函數一般擁有na.rm
參數,如果想要在計算時免除缺失值的影響,需要指定na.rm=T
。
> x <- c(1, 2, NA, 3)
> sum(x)
[1] NA
> sum(x, na.rm=T)
[1] 6
對於數據框,如果缺失值只集中於一小部分觀測,可以使用行刪除手段,具體地,可以使用na.omit()
函數,對所有含缺失值的觀測進行刪除。
newdata <- na.omit(leadership) # 函數生成的是一個映像,不會對原數據框產生影響
newdata
Section 2:日期值——as.Date()
要獲得當前的日期,可以使用Sys.Date()
函數;要獲得當前的日期與時間,可以使用date()
函數。
> date()
[1] "Fri Feb 19 13:56:35 2021"
> Sys.Date()
[1] "2021-02-19"
在R語言中,日期值常常是以字符串的形式輸入的,然后需要使用as.Date()
函數轉化成數值形式存儲的日期,其語法為
as.Date(x, "input_format")
這里,input_format
是用於讀入日期的適當格式,默認為yyyy-mm-dd
(年月日),其他格式化符號如下表。

對於本例,時間格式mm/dd/yy
,所以應當使用如下的修改編碼:
myformat <- "%m/%d/%y" # 編碼以字符串形式存儲
leadership$date <- as.Date(leadership$date, myformat)
要改變日期的格式以輸出,可以使用format()
函數,其使用格式是
format(x, format="output_format")
---
> m <- Sys.Date()
> format(m, format="%Y/%m/%d")
[1] "2021/02/19"
計算日期之間的差值,可以使用difftime()
函數,其使用格式是
difftime(date1, date2, units)
這里units
是時間單位,可以使用"auto", "secs", "mins", "days", "weeks"
等。
with(leadership, {
difftime(date[2], date[1], units = "days")
})
Time difference of 4 days
最后,要將日期轉化為字符串,使用as.character()
函數。
Section 3:類型轉換
要判斷某個值是否是某個類型,使用is.datatype()
函數;將數值轉換為某個類型,使用as.datatype()
函數。

其中,is.datatype()
返回一個TRUE
或FALSE
,可以用於控制流。
Part 3:數據框處理
Section 1:排序
使用order()
函數可以對向量進行排序,order()
會對向量重新編碼,接受若干個等長向量分別作為排序的有序關鍵字。
> x <- c("a", "e", "d", "d", "c", "b")
> y <- c(6, 5, 4, 3, 2, 1)
> order(x)
[1] 1 6 5 3 4 2
> order(x, y) # y作為第二排序標准
[1] 1 6 5 4 3 2
對數據框,也可以使用order()
函數作為條件排序,其原理是數據框可以按照一個有序向量進行排序。
with(leadership, {
newdata2 <<- leadership[order(gender, -age), 1:5]
})
> newdata2
managerID date country gender age
2 2 2014-10-28 US F 45
3 3 2014-10-01 UK F 25
5 5 2014-05-01 UK F NA
4 4 2014-10-12 UK M 39
1 1 2014-10-24 US M 32
注意,如果想要呈現完整的數據框,[contidion, ]
中逗號是不能省略的。
Section 2:數據框合並
橫向合並:即實現兩個數據框的內連接,通過一個或多個共有變量,可以使用merge()
函數,其用法為
total <- merge(dataframeA, dataframeB, by="ID") # by指定共有字段
如果不需要考慮外鍵,只是簡單地橫向合並,可以使用cbind()
函數,這要求每個對象擁有相同的行數,以相同的順序排序。
縱向合並:即向數據框中增加觀測值,可以使用rbind()
函數,這要求兩個數據框擁有相同的變量個數(對順序沒有要求)。
total <- rbind(dataframeA, dataframeB)
如果兩個數據框中變量不同,需要進行預處理:要么刪除dataframeA
中的多余變量,要么在dataframeB
中創建追加的變量,並將其值設為NA
。
Section 3:數據框取子集
選入變量:使用dataframe[, colindex]
即可,這里colindex
是變量的索引。事實上,如果需要保留全部觀測值,可以直接使用dataframe[colindex]
而並不需要逗號。另外,列索引也可以用變量名,如
myvars <- c("q1", "q2", "q3", "q4", "q5")
newdata <- leadership[myvars]
> newdata
q1 q2 q3 q4 q5
1 5 4 5 5 5
2 3 5 2 5 5
3 3 5 5 5 2
4 3 3 4 NA NA
5 2 2 1 2 1
刪除變量:可以使用如下的語句來刪除q4
,q5
兩個變量。
myvars <- names(leadership) %in% c("q4", "q5")
newdata <- leadership[!myvars]
這里,myvars
是一個邏輯變量,除了q4
和q5
是T
以外其他地方都是F
,因此取反,表示除了q4
和q5
是F
外其他都是T
(需要保留)。
另外,如果知道q4
和q5
是第9、第10個變量,可以簡單使用
newdata <- leadership[c(-9, -10)]
進行刪除。
選入觀測:選入觀測也可以使用邏輯變量。現在,選入觀測時間在2009-01-01
到2014-10-20
之間的觀測值,這里which
。
startdate <- as.Date("2009-01-01")
enddate <- as.Date("2014-10-20")
newdata <- leadership[leadership$date >= startdate & leadership$date <= enddate, ] # 逗號必須保留
選擇數據框的子集,最簡單的方法是使用subset()
函數,它可以一次性完成以上的功能,其使用格式如下:
subset(x, subset, select)
這里,x
是要傳入的數據框,subset
是要保留觀測的邏輯向量,select
是要保留變量的向量。
newdata <- subset(
leadership, gender == "M" & age > 25,
select = gender:q4
)
> newdata
gender age q1 q2 q3 q4
1 M 32 5 4 5 5
4 M 39 3 3 4 NA
可以看到,保留變量的向量可以直接用from:to
表達式,且from
和to
可以不必是數值。
如要隨機抽取觀測,可以使用sample()
函數,其用法是
sample(x, size, replace=FALSE)
這里,x
表示抽樣元素組成的向量,size
表示要抽取的元素數量,replace
表示是否是有放回抽樣。要是從數據集中抽樣,可以如此使用:
newsample <- leadership[sample(1:nrow(leadership), 3, replace=F), ]
Section 4:使用SQL查詢
如果是較大的數據集,可以使用SQL語句進行查找,這依賴於sqldf
庫中的sqldf
函數。
library(sqldf)
attach(mtcars)
search <- "SELECT * FROM mtcars WHERE carb=1 ORDER BY mpg"
newdf <- sqldf(search, row.names=T)
sqldf
中還有許多可選擇的參數,如stringsAsFactors
、row.names
等。