data.table包---转载(修改)

来源:转载

dataTable

dataTable

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

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: 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 1 0.3408 5

## 4: B 2 -0.7460 8

## 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

.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

结果与上一个是相同的。

7.串联操作可以把表达式聚合在一起并避免多余的中间变量

把多个操作串联起来,这等价于SQL中的having

set.seed(45L)

DT <- data.table(V1=c(1L,2L),V2=LETTERS[1:3],V3=round(rnorm(4),4),V4=1:12)

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 <- data.table(V1=c(1L,2L),

V2=LETTERS[1:3],

V3=round(rnorm(4),4),

V4=1:12)

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结合使用。

DT <- data.table(V1=c(1L,2L),

V2=LETTERS[1:3],

V3=round(rnorm(4),4),

V4=1:12)

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 1.8090 1

## 2: 2 B -0.2301 2

## 3: NA C -1.1304 3

## 4: NA A 0.2160 4

## 5: 1 NA 1.8090 5

## 6: 2 NA -0.2301 6

## 7: 1 A -1.1304 7

## 8: 2 B 0.2160 8

## 9: 1 C 1.8090 9

## 10: 2 A -0.2301 10

## 11: 1 B -1.1304 11

## 12: 2 C 0.2160 12

以上程序把给定的一组行和列都设置为了NA ### setname()

与set()同理,setname()可以修改给定的列名和行名,以下程序是

# 把名字为"V1"的列,设置为"newV1"

setnames(DT,"V1","new");DT

## new V2 V3 V4

## 1: 1 A 1.8090 1

## 2: 2 B -0.2301 2

## 3: NA C -1.1304 3

## 4: NA A 0.2160 4

## 5: 1 NA 1.8090 5

## 6: 2 NA -0.2301 6

## 7: 1 A -1.1304 7

## 8: 2 B 0.2160 8

## 9: 1 C 1.8090 9

## 10: 2 A -0.2301 10

## 11: 1 B -1.1304 11

## 12: 2 C 0.2160 12

# 把"V2","V3"列,设置为"V2.rating","V3.DataCamp"

setnames(DT,c("V2","V3"),c("V2.rating","V3.DataCamp"));DT

## new V2.rating V3.DataCamp V4

## 1: 1 A 1.8090 1

## 2: 2 B -0.2301 2

## 3: NA C -1.1304 3

## 4: NA A 0.2160 4

## 5: 1 NA 1.8090 5

## 6: 2 NA -0.2301 6

## 7: 1 A -1.1304 7

## 8: 2 B 0.2160 8

## 9: 1 C 1.8090 9

## 10: 2 A -0.2301 10

## 11: 1 B -1.1304 11

## 12: 2 C 0.2160 12

setcolorder()

setcolorder()可以用来修改列的顺序。

DT <- data.table(V1=c(1L,2L),

V2=LETTERS[1:3],

V3=round(rnorm(4),4),

V4=1:12)

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

# 这段代码会使得列的顺序变成:

DT

## V2 V1 V4 V3

## 1: A 1 1 1.2322

## 2: B 2 2 1.6094

## 3: C 1 3 0.4016

## 4: A 2 4 -0.2730

## 5: B 1 5 1.2322

## 6: C 2 6 1.6094

## 7: A 1 7 0.4016

## 8: B 2 8 -0.2730

## 9: C 1 9 1.2322

## 10: A 2 10 1.6094

## 11: B 1 11 0.4016

## 12: C 2 12 -0.2730

原文来自DataCamp课程的data.table官方速查表 原文链接:https://www.datacamp.com/community/tutorials/data-table-cheat-sheet 本文转载自雪晴数据网:http://www.xueqing.tv/cms/article/246

分享给朋友:
您可能感兴趣的文章:
随机阅读: