<!-- tabsets --> $(document).ready(function () { window.buildTabsets("TOC"); }); <!-- code folding --> dataTable wangchao 2016年7月18日 1.生成一個data.table對 ...
data.table
1.生成一個data.table對象
生成一個data.table對象,記為DT.
library(data.table)set.seed(45L)
DT <- data.table(V1=c(1L,2L),V2=LETTERS[1:3],V3=round(rnorm(4),4),V4=1:12)
DT
## V1 V2 V3 V4## 1: 1 A 0.3408 1
## 2: 2 B -0.7033 2
## 3: 1 C -0.3795 3
## 4: 2 A -0.7460 4
## 5: 1 B 0.3408 5
## 6: 2 C -0.7033 6
## 7: 1 A -0.3795 7
## 8: 2 B -0.7460 8
## 9: 1 C 0.3408 9
## 10: 2 A -0.7033 10
## 11: 1 B -0.3795 11
## 12: 2 C -0.7460 12
2.通過i來篩選數據集的行
通過數字來篩選數據集的行
選取第三行到第五行
DT[3:5,] #or DT[3:5]
## V1 V2 V3 V4## 1: 1 C -0.3795 3
## 2: 2 A -0.7460 4
## 3: 1 B 0.3408 5
基於使用快速自動索引條件,使用列名選擇行i
在V2這一列,選擇所有值為A的行
DT[V2 == "A"]
## V1 V2 V3 V4## 1: 1 A 0.3408 1
## 2: 2 A -0.7460 4
## 3: 1 A -0.3795 7
## 4: 2 A -0.7033 10
選擇多個值
選擇在這一列中包含value1或value2的所有值
DT[column %in% c("value1","value2")]
選擇V2這列中包含值A或C的所有行
DT[V2 %in% c("A","C")]
## V1 V2 V3 V4## 1: 1 A 0.3408 1
## 2: 1 C -0.3795 3
## 3: 2 A -0.7460 4
## 4: 2 C -0.7033 6
## 5: 1 A -0.3795 7
## 6: 1 C 0.3408 9
## 7: 2 A -0.7033 10
## 8: 2 C -0.7460 12
3.通過j來操作列
通過j來選擇一列
DT[,V2]## [1] "A" "B" "C" "A" "B" "C" "A" "B" "C" "A" "B" "C"
註意到V2這一列是以向量的形式返回的
通過j來選擇多列
DT[,.(V2,V3)]## V2 V3
## 1: A 0.3408
## 2: B -0.7033
## 3: C -0.3795
## 4: A -0.7460
## 5: B 0.3408
## 6: C -0.7033
## 7: A -0.3795
## 8: B -0.7460
## 9: C 0.3408
## 10: A -0.7033
## 11: B -0.3795
## 12: C -0.7460
V2與V3這兩列以data.table的形式返回
.()為list()的一個別名。如果使用.(),返回的為一個data.table對象。如果不使用.(),結果為返回一個向量。
在j上調用函數
DT[,sum(V1)]## [1] 18
以向量的形式返回V1列中所有元素的總和
在多列上進行計算
以data.table的形式,返回V1這列的所有元素之和與V3這列的標準差
DT[,.(sum(V1),sd(V3))]## V1 V2
## 1: 18 0.4546055
指定計算列的列名
類似上例,但有一個新的列名
DT[,.(Aggregate = sum(V1), Sd.V3 = sd(V3))]## Aggregate Sd.V3
## 1: 18 0.4546055
若列的長度不一,則會迴圈對齊
選擇V1這一列,並計算V3這列的標準差,將會得到一個標準差的值並迴圈補齊
DT[,.(V1, Sd.V3 = sd(V3))]## V1 Sd.V3
## 1: 1 0.4546055
## 2: 2 0.4546055
## 3: 1 0.4546055
## 4: 2 0.4546055
## 5: 1 0.4546055
## 6: 2 0.4546055
## 7: 1 0.4546055
## 8: 2 0.4546055
## 9: 1 0.4546055
## 10: 2 0.4546055
## 11: 1 0.4546055
## 12: 2 0.4546055
多個表達式可以包裹在花括弧中
輸出V2這一列並繪製V3這一列
DT[,{print(V2)plot(V3)
NULL}]
## [1] "A" "B" "C" "A" "B" "C" "A" "B" "C" "A" "B" "C" ## NULL
4.根據分組來操作j
根據分組來操作j
對V1中的每一類來計算V4列的和
DT[,.(V4.Sum = sum(V4)),by=V1]## V1 V4.Sum
## 1: 1 36
## 2: 2 42
通過使用.()控制多個列來操作j
與上例類似,但每一個分組包含V1和V2兩列
DT[,.(V4.Sum = sum(V4)),by=.(V1,V2)]## V1 V2 V4.Sum
## 1: 1 A 8
## 2: 2 B 10
## 3: 1 C 12
## 4: 2 A 14
## 5: 1 B 16
## 6: 2 C 18
在by中調用函數
以sign(V1-1)為分組,計算各個分組中V4列的和:
DT[,.(V4.Sum = sum(V4)),by=sign(V1-1)]
## sign V4.Sum
## 1: 0 36
## 2: 1 42
通過指定i行子集的分組進行操作
在前5行數據集中,通過V1列的分組來計算V4列的總和:
DT[1:5,.(V4.Sum = sum(V4)),by=V1]## V1 V4.Sum
## 1: 1 9
## 2: 2 6
使用函數.N來得到每個類別的總觀測數
在V1列中計算每個分組的觀測數
DT[,.N,by=V1]## V1 N
## 1: 1 6
## 2: 2 6
5.使用:=引用來添加或更新一列
在一行中使用:=引用來添加或更新列.
註意: 額外的指定 (DT <- DT[…])是多餘的 使用:=來更新V1列:
DT[, V1 := round(exp(V1),2)]這段代碼沒有顯式的返回結果,而V1列從[1] 1 2 1 2 … 變成了 [1] 2.72 7.39 2.72 7.39 …
使用:=引用來添加或更新多列
使用:=更新V1列和V2列:
DT[, c("V1","V2") := list(round(exp(V1),2), LETTERS[4:6])]同樣沒有顯式的返回結果,V1列的結果與上相同,V2列從[1] “A” “B” “C” “A” “B” “C” … 變成: [1] “D” “E” “F” “D” “E” “F” …
使用函數:=
上例的另一種寫法,但會在書寫時更易並齊。而且,當添加[]時,結果會返回在屏幕中
DT[, ':=' (V1 =round(exp(V1),2),V2 = LETTERS[4:6])][]## V1 V2 V3 V4
## 1: 3913724 D 0.3408 1
## 2: Inf E -0.7033 2
## 3: 3913724 F -0.3795 3
## 4: Inf D -0.7460 4
## 5: 3913724 E 0.3408 5
## 6: Inf F -0.7033 6
## 7: 3913724 D -0.3795 7
## 8: Inf E -0.7460 8
## 9: 3913724 F 0.3408 9
## 10: Inf D -0.7033 10
## 11: 3913724 E -0.3795 11
## 12: Inf F -0.7460 12
與上例變化相同,但是由於在語句最後添加了[],這一結果會返回至屏幕
通過使用:=來移除一列
移除V1列
DT[, V1 := NULL]無顯式的返回結果,但V1列變為NULL
通過使用:=來移除多列
移除V1列與V2列
DT[, c("V1","V2") := NULL]## Warning in `[.data.table`(DT, , `:=`(c("V1", "V2"), NULL)): Adding new
## column 'V1' then assigning NULL (deleting it).
無顯式的返回結果,但V1列與V2列變為NULL
將一個包含列名的變數用小括弧包裹起來,變數所傳遞的內容將會被刪除
註意:列名為Cols.chosen的列將會被刪除,這裡不是刪除“V1”,“V2”列
Cols.chosen = c("V1","V2")DT[, Cols.chosen := NULL]
## Warning in `[.data.table`(DT, , `:=`(Cols.chosen, NULL)): Adding new column
## 'Cols.chosen' then assigning NULL (deleting it).
無顯式的返回結果,列名為Cols.chosen的列將會被刪除
刪除指定變數Cols.chosen包含的V1列和V2列
DT[, (Cols.chosen) := NULL]## Warning in `[.data.table`(DT, , `:=`((Cols.chosen), NULL)): Adding new
## column 'V1' then assigning NULL (deleting it).
## Warning in `[.data.table`(DT, , `:=`((Cols.chosen), NULL)): Adding new
## column 'V2' then assigning NULL (deleting it).
無顯式的返回結果,列名為V1和V2的列變為NULL?
索引與鍵值
使用setkey()函數設置鍵值
setkey()函數可以在數據集DT上設置鍵值。當我們設置好key後,data.table會將數據按照key來排序。 在V2列上設置一個鍵值
set.seed(45L)DT <- data.table(V1=c(1L,2L),V2=LETTERS[1:3],V3=round(rnorm(4),4),V4=1:12)
DT
## V1 V2 V3 V4
## 1: 1 A 0.3408 1
## 2: 2 B -0.7033 2
## 3: 1 C -0.3795 3
## 4: 2 A -0.7460 4
## 5: 1 B 0.3408 5
## 6: 2 C -0.7033 6
## 7: 1 A -0.3795 7
## 8: 2 B -0.7460 8
## 9: 1 C 0.3408 9
## 10: 2 A -0.7033 10
## 11: 1 B -0.3795 11
## 12: 2 C -0.7460 12
setkey(DT,V2)
無顯示返回結果
使用鍵值來選擇行
使用鍵值可以更加有效地選擇行,由於已將V2設置了鍵值,將會返回該列中所有包含變數值A的行
DT["A"]## V1 V2 V3 V4
## 1: 1 A 0.3408 1
## 2: 2 A -0.7460 4
## 3: 1 A -0.3795 7
## 4: 2 A -0.7033 10
返回鍵值所在列(V2列)包含變數值A或變數值C的所有行
DT[c("A","C")]## V1 V2 V3 V4
## 1: 1 A 0.3408 1
## 2: 2 A -0.7460 4
## 3: 1 A -0.3795 7
## 4: 2 A -0.7033 10
## 5: 1 C -0.3795 3
## 6: 2 C -0.7033 6
## 7: 1 C 0.3408 9
## 8: 2 C -0.7460 12
mult參數
mult參數是用來控制i匹配到的哪一行的返回結果預設情況下會返回該分組的所有元素
返回匹配到鍵值所在列(V2列)所有行中的第一行
DT["A", mult ="first"]## V1 V2 V3 V4
## 1: 1 A 0.3408 1
返回匹配到鍵值所在列(V2列)所有行中的最後一行
DT["A", mult = "last"]## V1 V2 V3 V4
## 1: 2 A -0.7033 10
nomatch參數
nomatch參數用於控制,當在i中沒有到匹配數據的返回結果,預設為NA,也能設定為0。0意味著對於沒有匹配到的行將不會返回。 返回匹配到鍵值所在列(V2列)所有包含變數值A或D的所有行:
DT[c("A","D")]## V1 V2 V3 V4
## 1: 1 A 0.3408 1
## 2: 2 A -0.7460 4
## 3: 1 A -0.3795 7
## 4: 2 A -0.7033 10
## 5: NA D NA NA
變數值A匹配到了,而變數值D沒有,故返回NA。
返回匹配到鍵值所在列(V2列)所有包含值A或D的所有行:
DT[c("A","D"), nomatch = 0]## V1 V2 V3 V4
## 1: 1 A 0.3408 1
## 2: 2 A -0.7460 4
## 3: 1 A -0.3795 7
## 4: 2 A -0.7033 10
因為nomatch參數,值D沒有匹配到故不返回。
by=.EACHI參數
by=.EACHI允許按每一個已知i的子集分組,在使用by=.EACHI時需要設置鍵值
返回鍵值(V2列)中包含A或C的所有行中,V4列的總和。
DT[c("A","C"),sum(V4)]## [1] 52
返回鍵值所在列(V2列)中包含A的行在V4列總和與包含C的行在V4列的總和。
DT[c("A","C"),sum(V4), by=.EACHI]## V2 V1
## 1: A 22
## 2: C 30
使用setkey()設置一個多列主鍵
任意列都能使用setkey()來設置主鍵,這種方式可以選擇2個列作為一個主鍵。以下是一個等值連接V1列的每個組先根據V1排序,再根據V2排序。
setkey(DT,V1,V2)
無顯式返回結果
選擇鍵值1(V1列)為2且鍵值2(V2列)為C的行。
DT[.(2,"C")]## V1 V2 V3 V4
## 1: 2 C -0.7033 6
## 2: 2 C -0.7460 12
選擇鍵值1(V1列)為2且鍵值2(V2列)為A或C的行
DT[.(2,c("A","C"))]## V1 V2 V3 V4
## 1: 2 A -0.7460 4
## 2: 2 A -0.7033 10
## 3: 2 C -0.7033 6
## 4: 2 C -0.7460 12
6.data.table高級操作
.N
.N可以用來表示行的數量或者最後一行
在i處使用:
DT[.N-1]## V1 V2 V3 V4
## 1: 2 C -0.7033 6
返回每一列的倒數第二行 在j處使用:
DT[,.N-1]## [1] 11
返回倒數第二行所在的行數。 ### .()
.()是list()的一個別名,他們在data.table中是等價的。當只有一個元素的位置j或者by中,是不需要.()的。
在j中使用:
DT[,.(V2,V3)] #or DT[,list(V2,V3)]## V2 V3
## 1: A 0.3408
## 2: A -0.3795
## 3: B 0.3408
## 4: B -0.3795
## 5: C -0.3795
## 6: C 0.3408
## 7: A -0.7460
## 8: A -0.7033
## 9: B -0.7033
## 10: B -0.7460
## 11: C -0.7033
## 12: C -0.7460
在by中使用:
DT[, mean(V3),by=.(V1,V2)]## V1 V2 V1
## 1: 1 A -0.01935
## 2: 1 B -0.01935
## 3: 1 C -0.01935
## 4: 2 A -0.72465
## 5: 2 B -0.72465
## 6: 2 C -0.72465
以V1,V2為分組,對V3求均值 ### .SD參數
.SD是一個data.table,他包含了各個分組,除了by中的變數的所有元素。.SD只能在位置j中使用:
DT[, print(.SD), by=V2]## V1 V3 V4
## 1: 1 0.3408 1
## 2: 1 -0.3795 7
## 3: 2 -0.7460 4
## 4: 2 -0.7033 10
## V1 V3 V4
## 1: 1 0.3408 5
## 2: 1 -0.3795 11
## 3: 2 -0.7033 2
## 4: 2 -0.7460 8
## V1 V3 V4
## 1: 1 -0.3795 3
## 2: 1 0.3408 9
## 3: 2 -0.7033 6
## 4: