DataCamp課程的官方速查表(本篇內容由我跟小夥伴一年前翻譯,最開始掛在雪晴數據網上)python
我的認爲R中最應該學習的一個R包就是data.table
了,本人16年參加一些數據挖掘比賽,數據量較大,開始學習data.table
來進行快速數據清洗,這邊的快速有2方面:git
data.table
的運行速度快data.table
代碼簡短,寫起來快dt[i,j,by] #一行代碼解決全部
能夠說data.table
是R數據處理的極限了(不喜勿噴),運行速度也快於python
的pandas
下面將我看到的一些關於data.table
的中文翻譯文章給出連接,包括當時我本身翻譯的文章,方便你們查詢,也方便我本身查詢。github
r-damao
,裏面不少data.table
的精彩內容以上共9篇關於data.table
的文章以及大貓的微信公衆號中的一些文章,都是中文翻譯好的,都看完就基本入門了.spring
R中的data.table
包提供了一個data.frame
的高級版本,讓你的程序作數據整型的運算速度大大的增長。data.table
已經在金融,基因工程學等領域大放光彩。他尤爲適合那些須要處理大型數據集(好比1GB到100GB)須要在內存中處理數據的人。不過這個包的一些符號並非很容易掌握,由於這些操做方式在R中比較少見。這也是這篇文章的目的,爲了給你們提供一個速查的手冊。微信
通用格式: DT[i, j, by],對於數據集DT,選取子集行i,經過by分組計算japp
生成一個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
選取第三行到第五行學習
> 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
在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的全部值code
> 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
> DT[,V2] [1] "A" "B" "C" "A" "B" "C" "A" "B" "C" "A" "B" "C"
注意到V2這一列是以向量的形式返回的
> 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對象。若是不使用.(),結果爲返回一個向量。
> 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: 2 0.4546055 6: 1 0.4546055 7: 2 0.4546055 8: 1 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" #And a plot NULL
對V1中的每一類來計算V4列的和
> DT[,.(V4.Sum = sum(V4)),by=V1] V1 V4.Sum 1: 1 36 2: 2 42
與上例相似,但每個分組包含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
以sign(V1-1)爲分組,計算各個分組中V4列的和:
> DT[,.(V4.Sum = sum(V4)),by=sign(V1-1)] sign V4.Sum 1: 0 36 2: 1 42
在前5行數據集中,經過V1列的分組來計算V4列的總和:
> DT[1:5,.(V4.Sum = sum(V4)),by=V1] V1 V4.Sum 1: 1 9 2: 2 6
在V1列中計算每一個分組的觀測數
> DT[,.N,by=V1] V1 N 1: 1 6 2: 2 6
注意: 額外的指定 (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列
> DT[, V1 := NULL]
無顯式的返回結果,但V1列變爲NULL
移除V1列與V2列
> DT[, c("V1","V2") := NULL]
無顯式的返回結果,但V1列與V2列變爲NULL
將一個包含列名的變量用小括號包裹起來,變量所傳遞的內容將會被刪除
注意:列名爲Cols.chosen的列將會被刪除,這裏不是刪除"V1","V2"列
> Cols.chosen = c("V1","V2") > DT[, Cols.chosen := NULL]
無顯式的返回結果,列名爲Cols.chosen的列將會被刪除
刪除指定變量Cols.chosen包含的V1列和V2列
> DT[, (Cols.chosen) := NULL]
無顯式的返回結果,列名爲V1和V2的列變爲NULL##索引與鍵值
(注意:因爲上面進行了更新操做,此處須要從新運行文章最開始的代碼,生成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)
setkey()函數能夠在數據集DT上設置鍵值。當咱們設置好key後,data.table會將數據按照key來排序。
在V2列上設置一個鍵值
> 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參數是用來控制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參數用於控制,當在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
容許按每個已知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()來設置主鍵,這種方式行能夠選擇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
.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: 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
在by中使用:
> DT[, mean(V3),by=.(V1,V2)] V1 V2 V1 1: 1 A -0.01935 2: 2 B -0.72465 3: 1 C -0.01935 4: 2 A -0.72465 5: 1 B -0.01935 6: 2 C -0.72465
以V1,V2爲分組,對V3求均值
.SD
是一個data.table,他包含了各個分組,除了by中的變量的全部元素。.SD
只能在位置j中使用:
> DT[, print(.SD), by=V2] V1 V3 V4 1: 1 0.3408 1 2: 2 -0.7460 4 3: 1 -0.3795 7 4: 2 -0.7033 10 V1 V3 V4 1: 2 -0.7033 2 2: 1 0.3408 5 3: 2 -0.7460 8 4: 1 -0.3795 11 V1 V3 V4 1: 1 -0.3795 3 2: 2 -0.7033 6 3: 1 0.3408 9 4: 2 -0.7460 12 Empty data.table (0 rows) of 1 col: V2
以V2爲分組,選擇每組的第一和最後一列:
> DT[,.SD[c(1,.N)], by=V2] V2 V1 V3 V4 1: A 1 0.3408 1 2: A 2 -0.7033 10 3: B 2 -0.7033 2 4: B 1 -0.3795 11 5: C 1 -0.3795 3 6: C 2 -0.7460 12
以V2爲分組,計算.SD
中全部元素的和:
> DT[, lapply(.SD, sum), by=V2] V2 V1 V3 V4 1: A 6 -1.488 22 2: B 6 -1.488 26 3: C 6 -1.488 30
.SDcols
常於.SD
用在一塊兒,他能夠指定.SD
中所包含的列,也就是對.SD
取子集:
> DT[, lapply(.SD,sum), by=V2,.SDcols = c("V3","V4")] V2 V3 V4 1: A -1.488 22 2: B -1.488 26 3: C -1.488 30
.SDcols
也能夠是一個函數的返回值:
> DT[, lapply(.SD,sum), by=V2,.SDcols = paste0("V",3:4)] V2 V3 V4 1: A -1.488 22 2: B -1.488 26 3: C -1.488 30
結果與上一個是相同的。
> DT<-DT[, .(V4.Sum = sum(V4)),by=V1] > DT[V4.Sum > 35] #no chaining V1 V4.Sum 1: 1 36 2: 2 42
這個是不使用串聯的方法,先以V1爲分組,對V4求和,而後再把分組總和大於35的取出來。
使用串聯的方法:
> DT[, .(V4.Sum = sum(V4)),by=V1][V4.Sum > 35 ] V1 V4.Sum 1: 1 36 2: 2 42
分組求和以後對V1進行排序:
> DT[, .(V4.Sum = sum(V4)),by=V1][order(-V1)] V1 V4.Sum 1: 2 42 2: 1 36
set()
家族set()
一般用來更新給定的行和列的值,要注意的是,他不能跟by結合使用。
> rows = list(3:4,5:6) > cols = 1:2 > for (i in seq_along(rows)) + { + set(DT, + i=rows[[i]], + j = cols[i], + value = NA) +} > DT V1 V2 V3 V4 1: 1 A -0.0559 1 2: 2 B -0.4450 2 3: NA C 0.0697 3 4: NA A -0.1547 4 5: 1 NA -0.0559 5 6: 2 NA -0.4450 6 7: 1 A 0.0697 7 8: 2 B -0.1547 8
以上程序把給定的一組行和列都設置爲了NA
與set()
同理,setname()
能夠修改給定的列名和行名,如下程序是
#把名字爲"old"的列,設置爲"new" > setnames(DT,"old","new") #把"V2","V3"列,設置爲"V2.rating","V3.DataCamp" > setnames(DT,c("V2","V3"),c("V2.rating","V3.DataCamp"))
setcolorder()
能夠用來修改列的順序。
setcolorder(DT,c("V2","V1","V4","V3"))
這段代碼會使得列的順序變成:
[1] "V2" "V1" "V4" "V3"
dt[order(-prob),字段[1],.(分組)] dt[order(-label_prob),.(shop_id_yc = shop_id[1]),.(row_id)] 或者 dt[,.SD[which.max(label_prob)],.(row_id)] 或者 setorder(dt, -x)[, head(.SD, 5), .(row_id)] #setorder 稍快於order
dt[!duplicated(dt$id),]