R之data.table速查手冊

R語言data.table速查手冊

介紹

R中的data.table包提供了一個data.frame的高級版本,讓你的程序作數據整型的運算速度大大的增長。data.table已經在金融,基因工程學等領域大放光彩。他尤爲適合那些須要處理大型數據集(好比 1GB 到100GB)須要在內存中處理數據的人。不過這個包的一些符號並非很容易掌握,由於這些操做方式在R中比較少見。這也是這篇文章的目的,爲了給你們提供一個速查的手冊。php


data.table的通用格式: DT[i, j, by],對於數據集DT,選取子集行i,經過by分組計算jcss

1.生成一個data.table對象

生成一個data.table對象,記爲DT.html

> 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 -1.1727 1 2: 2 B -0.3825 2 3: 1 C -1.0604 3 4: 2 A 0.6651 4 5: 1 B -1.1727 5 6: 2 C -0.3825 6 7: 1 A -1.0604 7 8: 2 B 0.6651 8 9: 1 C -1.1727 9 10: 2 A -0.3825 10 11: 1 B -1.0604 11 12: 2 C 0.6651 12

2.經過i來篩選數據集的行

經過數字來篩選數據集的行

選取第三行到第五行git

> DT[3:5,] #or DT[3:5] V1 V2 V3 V4 1: 1 C -1.0604 3 2: 2 A 0.6651 4 3: 1 B -1.1727 5

基於使用快速自動索引條件,使用列名選擇行i

在V2這一列,選擇全部值爲A的行github

> DT[ V2 == "A"]
V1 V2 V3 V4
1: 1 A -1.1727 1 2: 2 A 0.6651 4 3: 1 A -1.0604 7 4: 2 A -0.3825 10

選擇多個值:

選擇在這一列中包含value1或value2的全部值spring

> DT[column %in% c("value1","value2")]

選擇V2這列中包含值A或C的全部行sql

> DT[ V2 %in% 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

3.經過j來操做列

經過j來選擇一列

> DT[,V2]
[1]"A" "A" "A" "A" "B" "B" "B" "B" "C" "C" "C" "C"

注意到V2這一列是以向量的形式返回的json

經過j來選擇多列

> DT[,.(V2,V3)] V2 V3 1: A 0.3408 2: A -0.7460 3: A -0.3795 4: A -0.7033 5: B -0.7033 6: B 0.3408 7: B -0.7460 8: B -0.3795 9: C -0.3795 10: C -0.7033 11: C 0.3408 12: C -0.7460

V2與V3這兩列以data.table的形式返回ruby

.()爲list()的一個別名。若是使用.(),返回的爲一個data.table對象。若是不使用.(),結果爲返回一個向量。markdown

在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: 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" "A" "A" "A" "B" "B" "B" "B" "C" "C" "C" "C" #And a plot 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 A 14 3: 2 B 10 4: 1 B 16 5: 1 C 12 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 8 2: 2 16

使用函數.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列

> 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##索引與鍵值

使用setkey()函數設置鍵值

setkey()函數能夠在數據集DT上設置鍵值。當咱們設置好key後,data.table會將數據按照key來排序。 
在V2列上設置一個鍵值

> setkey(DT,V2)

無顯示返回結果

使用鍵值來選擇行

使用鍵值能夠更加有效地選擇行 
因爲已將V2設置了鍵值,將會返回該列中全部包含變量值A的行

> DT["A"]
   V1 V2 V3 V4
1: 1 A -1.1727 1 2: 2 A 0.6651 4 3: 1 A -1.0604 7 4: 2 A -0.3825 10

返回鍵值所在列(V2列)包含變量值A或變量值C的全部行

> DT[c("A","C")] V1 V2 V3 V4 1: 1 A -0.8981 1 2: 2 A -0.1745 4 3: 1 A -0.5014 7 4: 2 A -0.3348 10 5: 1 C -0.5014 3 6: 2 C -0.3348 6 7: 1 C -0.8981 9 8: 2 C -0.1745 12

mult參數

mult參數是用來控制i匹配到的哪一行的返回結果默認狀況下會返回該分組的全部元素 
返回匹配到鍵值所在列(V2列)全部行中的第一行

> DT["A", mult ="first"] V1 V2 V3 V4 1: 1 A -1.1727 1

返回匹配到鍵值所在列(V2列)全部行中的最後一行

> DT["A", mult = "last"] V1 V2 V3 V4 1: 2 A -0.3825 10

nomatch參數

nomatch參數用於控制,當在i中沒有到匹配數據的返回結果,默認爲NA,也能設定爲0。0意味着對於沒有匹配到的行將不會返回。 
返回匹配到鍵值所在列(V2列)全部包含變量值A或D的全部行:

> DT[c("A","D")] V1 V2 V3 V4 1: 1 A -1.1727 1 2: 2 A 0.6651 4 3: 1 A -1.0604 7 4: 2 A -0.3825 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 -1.1727 1 2: 2 A 0.6651 4 3: 1 A -1.0604 7 4: 2 A -0.3825 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.3825 6 2: 2 C 0.6651 12

選擇鍵值1(V1列)爲2且鍵值2(V2列)爲A或C的行

> DT[.(2,c("A","C"))] V1 V2 V3 V4 1: 2 A 0.6651 4 2: 2 A -0.3825 10 3: 2 C -0.3825 6 4: 2 C 0.6651 12

6.data.table高級操做

.N

.N能夠用來表示行的數量或者最後一行

在i處使用:

> DT[.N-1] V1 V2 V3 V4 1: 1 B -0.5765 11

返回每一列的倒數第二行 
在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.8313 2: B 0.7615 3: C -0.5765

在by中使用:

> DT[, mean(V3),by=.(V1,V2)]
   V1 V2       V1
1: 1 A -0.70390 2: 2 B 0.06755 3: 1 C -0.70390 4: 2 A 0.06755 5: 1 B -0.70390 6: 2 C 0.06755

以V1,V2爲分組,對V3求均值

.SD參數

.SD是一個data.table,他包含了各個分組,除了by中的變量的全部元素。.SD只能在位置j中使用:

> DT[, print(.SD), by=V2] V1 V3 V4 1: 1 -0.8313 1 2: 2 -0.6264 4 3: 1 -0.5765 7 4: 2 0.7615 10 V1 V3 V4 1: 2 0.7615 2 2: 1 -0.8313 5 3: 2 -0.6264 8 4: 1 -0.5765 11 V1 V3 V4 1: 1 -0.5765 3 2: 2 0.7615 6 3: 1 -0.8313 9 4: 2 -0.6264 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.8313 1 2: A 2 0.7615 10 3: B 2 0.7615 2 4: B 1 -0.5765 11 5: C 1 -0.5765 3 6: C 2 -0.6264 12

以V2爲分組,計算.SD中全部元素的和:

> DT[, lapply(.SD, sum), by=V2]
   V2 V1      V3 V4
1: A 6 -1.2727 22 2: B 6 -1.2727 26 3: C 6 -1.2727 30

.SDcols

.SDcols常於.SD用在一塊兒,他能夠指定.SD中所包含的列,也就是對.SD取子集:

> DT[, lapply(.SD,sum), by=V2,
+    .SDcols = c("V3","V4")] V2 V3 V4 1: A -1.2727 22 2: B -1.2727 26 3: C -1.2727 30

.SDcols也能夠是一個函數的返回值:

> DT[, lapply(.SD,sum), by=V2,
+    .SDcols = paste0("V",3:4)] V2 V3 V4 1: A -1.2727 22 2: B -1.2727 26 3: C -1.2727 30

結果與上一個是相同的。

7.串聯操做能夠把表達式聚合在一塊兒並避免多餘的中間變量

把多個操做串聯起來,這等價於SQL中的having

> 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

8.使用set()家族

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

setname()

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()能夠用來修改列的順序。

setcolorder(DT,c("V2","V1","V4","V3"))

這段代碼會使得列的順序變成:

[1] "V2" "V1" "V4" "V3"

栗子🌰:

首先介紹下data.table的語法,以下所示:

 

data.table包中,咱們可使用:=引用來添加或更新列

內置的 order() 函數 * 咱們能夠對一個字符型的列,使用減號「-」,來實現降序排列。

當咱們用list()的時候,返回的是data.table,不用list()時,返回的是向量。通常建議加上list(),除非你就是想要獲得向量格式的數據。

# select取子集方法之subset(x, subset, select) 
注:subset特指對列的選擇,select特指對行的選擇, with = FALSE 來引用列名

select列

* 既然列能夠做爲變量被引用,咱們能夠直接引用咱們想選取的列。

* 既然咱們想選取全部的行,則可毋需指定參數 i。

* 返回了全部行的 arr_delay 列。

特殊的語法

.SD: data.table提供一個特殊的語法,形式是 .SD。它是 Subset of Data 的縮寫。

它自身就是一個data.table,包含經過by 分組後的每一組。 回憶一下,一個data.table本質上是一個list,它們的列包含的元素個數都相同(其實就是行數)。

說明:

* .SD 包含除了分組依據的那一列之外的全部列。 * 返回值依舊保持了原數據的順序。首先打印出來的是 ID=「b」 的數據,而後是 ID=「a」 的,最後是 ID=「c」 的。

爲了對複數的列進行計算,咱們能夠簡單地使用函數 lapply()。

說明:

* .SD 分別包含了ID是 a、b、c的全部行,它們分別對應了各自的組。咱們應用函數 lapply() 對每列計算平均值。 * 每一組返回包含三個平均數的list,這些構成了最終返回的data.table。 * 既然函數 lapply() 返回 list,咱們就不須要在外面多加 .() 了。

-如何指定但願計算平均值的列

.SDcols 使用參數 .SDcols。它接受列名或者列索引。好比,.SDcols = c("arr_delay", "dep_delay")能確保.SD之包含 arr_delay 和 dep_delay 這兩列。 和 with = FALSE 同樣,咱們也可使用 - 或者 ! 來移除列。好比,咱們指定 !(colA:colB) 或者 -(colA:colB)表示移除從 colA 到 colB 的全部列。 

 

總結

data.table的語法形式是:

DT[i, j, by] 

指定參數i:

* 相似於data.frame,咱們能夠subset行,除非不須要重複地使用 DT$,既然咱們能將列當作變量來引用。 * 咱們可使用order()排序。爲了獲得更快速的效果,order()函數內部使用了data.table的快速排序。 咱們能夠經過參數i作更多的事,獲得更快速的選取和連結。咱們能夠在教程「Keys and fast binary search based subsets」和「Joins and rolling joins」中學到這些。 

指定參數j:

* 以data.table的形式選取列:DT[, .(colA, colB)]。 * 以data.frame的形式選取列:DT[, c("colA", "colB"), with=FALSE]。 * 按列進行計算:DT[, .(sum(colA), mean(colB))]。 * 若是須要:DT[, .(sA =sum(colA), mB = mean(colB))]。 * 和i共同使用:DT[colA > value, sum(colB)]。 

指定參數by:* 經過by,咱們能夠指定列,或者列名,甚至表達式,進行分組。參數j能夠很靈活地配置參數i和by實現強大的功能。

* by能夠指定多個列,也能夠指定表達式。 * 咱們能夠用 keyby,對分組的結果自動排序。 * 咱們能夠在參數j中指定 .SD 和 .SDcols,對複數的列進行操做。例如: 1.把函數fun 應用到全部 .SDcols指定的列上,同時對參數by指定的列進行分組:DT[, lapply(.SD, fun), by=., .SDcols=...]。 2.返回每組冊前兩行:DT[, head(.SD, 2), by=.]。 3.三個參數聯合使用:DT[col > val, head(.SD, 1), by=.]
 

原文來自DataCamp課程的data.table官方速查表 
原文連接:The data.table R package cheat sheet

     http://youngspring1.github.io/post/2016/2016-03-13-datatable1/

相關文章
相關標籤/搜索