data frame 的索引使用方式有許多種,向量和矩陣所使用的四種索引(正整數、負整數、邏輯與字元向量)都可以直接用於 data frame:
x.data.frame <- data.frame( x = letters[1:6], y = rnorm(6), z = runif(6) > 0.5 ) x.data.frame[2:4, 2]
[1] -0.2310849 1.0684388 0.9391086
x.data.frame[2:4, -2]
x z 2 b TRUE 3 c TRUE 4 d FALSE
x.data.frame[c(FALSE, TRUE, TRUE, TRUE, FALSE), c("x", "z")]
x z 2 b TRUE 3 c TRUE 4 d FALSE
只有取出 data frame 的單一行(column)時,傳回的資料類型會是向量,但若是取出多行時,傳回的資料就會是另一個 data frame:
class(x.data.frame[2:4, 2])
[1] "numeric"
class(x.data.frame[2:4, -2])
[1] "data.frame"
如果只需要選取單一行的資料,可以使用列表變數的索引方式(雙中括號 [[]]
加上正整數或名稱、錢字號 $
加上名稱),以下幾種寫法都是相同的。
x.data.frame$x
[1] a b c d e f Levels: a b c d e f
x.data.frame[[1]]
[1] a b c d e f Levels: a b c d e f
x.data.frame[["x"]]
[1] a b c d e f Levels: a b c d e f
如果要取出一行中部分的元素,可以再堆疊一個中括號來指定元素的索引:
x.data.frame$x[2:4]
[1] b c d Levels: a b c d e f
x.data.frame[[1]][2:4]
[1] b c d Levels: a b c d e f
x.data.frame[["x"]][2:4]
[1] b c d Levels: a b c d e f
如果想要篩選 data frame 中的資料,可以使用條件判斷式再配合索引的方式來處理:
x.data.frame[x.data.frame$y > 0 | x.data.frame$z, "x"]
[1] a b d e f Levels: a b c d e f
如果不想使用這麼複雜的寫法,也可以改用 subset
函數,它的功能相同,但是寫法較簡潔:
subset(x.data.frame, y > 0 | z, x)
x 1 a 2 b 4 d 5 e 6 f
subset
函數第一個參數是要進行篩選的 data frame 變數,而第二個參數是指定列(row)的索引,第三個參數則是行(column)的索引,若最後一個行索引參數省略,就會取出所有行中的資料。
data frame 跟矩陣一樣可以使用 t
函數來轉向:
x.data.frame <- data.frame( x = letters[1:6], y = rnorm(6), z = runif(6) > 0.5 ) t(x.data.frame)
不過將 data frame 轉向之後,所有的資料都會換轉為同一種類型,而且轉換之後的變數會是一個矩陣。
若要結合多個 data frames,可以使用 cbind
或 rbind
,rbind
在結合多個 data frames 時,會自動判斷每個行的名稱,將相同名稱的行對應起來,行的排列順序不會影響合併結果:
x.data.frame <- data.frame( x = letters[1:6], y = rnorm(6), z = runif(6) > 0.5 ) y.data.frame <- data.frame( y = rnorm(6, 7, 9), z = runif(6) < 0.5, x = letters[7:12] ) rbind(x.data.frame, y.data.frame)
x y z 1 a -0.3059567 TRUE 2 b 0.6109400 TRUE 3 c 0.5408157 FALSE 4 d 0.8020496 FALSE 5 e -0.9348107 FALSE 6 f 1.2134915 FALSE 7 g -0.3173948 TRUE 8 h 25.6336216 TRUE 9 i -16.4824389 TRUE 10 j 5.3940237 TRUE 11 k 11.9232029 FALSE 12 l 16.6851942 TRUE
cbind
函數在合併 data frames 時,並不會檢查行的名稱,所以要注意行名稱重複的問題:
cbind(x.data.frame, y.data.frame)
x y z y z x 1 a -0.3059567 TRUE -0.3173948 TRUE g 2 b 0.6109400 TRUE 25.6336216 TRUE h 3 c 0.5408157 FALSE -16.4824389 TRUE i 4 d 0.8020496 FALSE 5.3940237 TRUE j 5 e -0.9348107 FALSE 11.9232029 FALSE k 6 f 1.2134915 FALSE 16.6851942 TRUE l
如果兩個 data frames 要依照某個特定的行來合併資料,可以使用 merge
函數:
x.data.frame <- data.frame( x = letters[1:6], foo.x = rnorm(6), bar.x = runif(6) > 0.5 ) x.data.frame
x foo.x bar.x 1 a -0.06067850 TRUE 2 b -0.01201291 TRUE 3 c -0.28666529 FALSE 4 d 1.64905115 FALSE 5 e -0.39324483 TRUE 6 f 0.25352265 TRUE
y.data.frame <- data.frame( foo.y = rnorm(6, 7, 9), bar.y = runif(6) < 0.5, x = letters[3:8] ) y.data.frame
foo.y bar.y x 1 -2.9982815 TRUE c 2 -0.1559176 FALSE d 3 12.6673980 TRUE e 4 6.6994744 TRUE f 5 0.3809737 FALSE g 6 3.3026685 FALSE h
使用 merge
將 x.data.frame
與 y.data.frame
依據 x
欄位結合:
merge(x.data.frame, y.data.frame, by = "x")
x foo.x bar.x foo.y bar.y 1 c -0.2866653 FALSE -2.9982815 TRUE 2 d 1.6490511 FALSE -0.1559176 FALSE 3 e -0.3932448 TRUE 12.6673980 TRUE 4 f 0.2535227 TRUE 6.6994744 TRUE
在使用 merge
合併 data frames 時,如果有些 x
欄位的值只出現在其中一個 data frame 中,而在另外一個 data frame 中找不到這個值的話,這一筆資料就會被忽略,如果需要將這樣不完全的資料也都保留的話,可以加上 all = TRUE
參數:
merge(x.data.frame, y.data.frame, by = "x", all = TRUE)
x foo.x bar.x foo.y bar.y 1 a -0.06067850 TRUE NA NA 2 b -0.01201291 TRUE NA NA 3 c -0.28666529 FALSE -2.9982815 TRUE 4 d 1.64905115 FALSE -0.1559176 FALSE 5 e -0.39324483 TRUE 12.6673980 TRUE 6 f 0.25352265 TRUE 6.6994744 TRUE 7 g NA NA 0.3809737 FALSE 8 h NA NA 3.3026685 FALSE
對於含有數值資料的 data frame,我們可以使用 colSums
與 colMeans
函數來計算整個行的總和與平均:
colSums(x.data.frame[, 2:3])
foo.x bar.x 1.149972 4.000000
colMeans(x.data.frame[, 2:3])
foo.x bar.x 0.1916620 0.6666667
若要計算列的總和與平均,則可使用 rowSums
與 rowMeans
函數,用法都是類似的。