8 min read

data.table学习笔记5

  • data.table的特点:减小计算复杂度,降低计算时间

1. 1建立两个数据集:DF(data.frame)和DT(data.table)

DF = data.frame(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9) #data frame类型数据集
DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9) #data.table类型数据集

1.2 比较DF和DT,注意函数identical,是比较两个对象的安全方式。

DF和DT本质上都是list类型?

DF
##   x y v
## 1 b 1 1
## 2 b 3 2
## 3 b 6 3
## 4 a 1 4
## 5 a 3 5
## 6 a 6 6
## 7 c 1 7
## 8 c 3 8
## 9 c 6 9
DT
##    x y v
## 1: b 1 1
## 2: b 3 2
## 3: b 6 3
## 4: a 1 4
## 5: a 3 5
## 6: a 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
identical(dim(DT),dim(DF)) #比较维数是否相同
## [1] TRUE
identical(DF$a,DT$a) #比较a列是否相同
## [1] TRUE
is.list(DF) #检测是否是list类型
## [1] TRUE
is.list(DT) #同上
## [1] TRUE
is.data.frame(DT) #data.table是否是data.frame类型
## [1] TRUE
tables() #用来统计全局环境中有多少个data.table。
##    NAME NROW NCOL MB  COLS KEY
## 1:   DT    9    3  0 x,y,v    
## Total: 0MB

1.3 基本数据提取操作

DT[2] #提取第2行
##    x y v
## 1: b 3 2
DT[3:2] #提取第3行和第2行
##    x y v
## 1: b 6 3
## 2: b 3 2
DT[order(x)] #根据x列排序DT数据集
##    x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 4: b 1 1
## 5: b 3 2
## 6: b 6 3
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
DT[order(x),] #同上
##    x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 4: b 1 1
## 5: b 3 2
## 6: b 6 3
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
DT[y>2] #提取y>2的所有数据行
##    x y v
## 1: b 3 2
## 2: b 6 3
## 3: a 3 5
## 4: a 6 6
## 5: c 3 8
## 6: c 6 9
DT[y>2 & v>5] #提取满足条件y>2 并且v>5的所有数据行
##    x y v
## 1: a 6 6
## 2: c 3 8
## 3: c 6 9
DT[!2:4] #剔除2,3,4行后的数据集
##    x y v
## 1: b 1 1
## 2: a 3 5
## 3: a 6 6
## 4: c 1 7
## 5: c 3 8
## 6: c 6 9
DT[-(2:4)] #同上
##    x y v
## 1: b 1 1
## 2: a 3 5
## 3: a 6 6
## 4: c 1 7
## 5: c 3 8
## 6: c 6 9

1.4 选择列,计算列

DT[,v] #选择v列返回向量
## [1] 1 2 3 4 5 6 7 8 9
DT[,list(v)] #同上
##    v
## 1: 1
## 2: 2
## 3: 3
## 4: 4
## 5: 5
## 6: 6
## 7: 7
## 8: 8
## 9: 9
DT[,.(v)] #同上,.()等同于list()
##    v
## 1: 1
## 2: 2
## 3: 3
## 4: 4
## 5: 5
## 6: 6
## 7: 7
## 8: 8
## 9: 9
DT[,sum(v)] #计算v列的和,返回一个向量
## [1] 45
DT[,.(sum(v))] #同上,但是返回一个data.table类型,列名V1
##    V1
## 1: 45
DT[,.(sv=sum(v))] #同上,命名为sv
##    sv
## 1: 45
DT[,.(v,v*2)] #生成一个新的数据集,包括v和v*2两列
##    v V2
## 1: 1  2
## 2: 2  4
## 3: 3  6
## 4: 4  8
## 5: 5 10
## 6: 6 12
## 7: 7 14
## 8: 8 16
## 9: 9 18

1.5 同时筛选行列

DT[2:3,sum(v)] #返回一个向量
## [1] 5
DT[2:3,.(sum(v))] #返回一个data.table,列命名为V1
##    V1
## 1:  5
DT[2:3,.(sv=sum(v))] #返回一个data.table,列命名为sv
##    sv
## 1:  5
DT[2:5,cat(v,"\n")] #v列2-5行,通过cat连接输出为一个字符串,不明白为什么有一个NULL
## 2 3 4 5
## NULL

1.6 通过data.frame的方式提取数据

DT[,2,with=FALSE] #提取2列的数据,with参数,控制列是否可以运算
##    y
## 1: 1
## 2: 3
## 3: 6
## 4: 1
## 5: 3
## 6: 6
## 7: 1
## 8: 3
## 9: 6
DT[,sum(2),with=FALSE] #with=FALSE,表示列不可运算,返回与上式相同的结果
##    y
## 1: 1
## 2: 3
## 3: 6
## 4: 1
## 5: 3
## 6: 6
## 7: 1
## 8: 3
## 9: 6
DT[,sum(v),with=TRUE] #v列之和
## [1] 45
#DT[,sum(v),with=FALSE] #这种格式错误,不能操作v列
DT[["v"]] #提取v列更快的方式
## [1] 1 2 3 4 5 6 7 8 9

1.7 组操作

DT[,sum(v),by=x] #依据x列分组,求v列和
##    x V1
## 1: b  6
## 2: a 15
## 3: c 24
DT[,sum(v),keyby=x] #依据x列分组,求v列和,结果按照x列排序
##    x V1
## 1: a 15
## 2: b  6
## 3: c 24
DT[,sum(v),keyby=x][order(x)] #结果同上,但是链式表达式操作
##    x V1
## 1: a 15
## 2: b  6
## 3: c 24

1.8 快速数据集提取,二级索引形式

DT["a",on="x"] #on开启二级索引形式
##    x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
DT["a",on=.(x)] #更加方便的形式,不用写双引号
##    x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
DT[.("a"),on=.(x)] #作用同上
##    x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
DT[x=="a"] #on 传统形式,然而内部进行了优化,速度同上
##    x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
DT[x!="b" | y!=3] #没有进行优化
##    x y v
## 1: b 1 1
## 2: b 6 3
## 3: a 1 4
## 4: a 3 5
## 5: a 6 6
## 6: c 1 7
## 7: c 3 8
## 8: c 6 9
DT[.("b",3),on=c("x","y")] #二级索引优化
##    x y v
## 1: b 3 2
DT[.("b",3),on=.(x,y)] #二级索引,简化去除引号
##    x y v
## 1: b 3 2
DT[.("b",1:2),on=.(x,y)] #不匹配的返回NA
##    x y  v
## 1: b 1  1
## 2: b 2 NA
DT[.("b",1:2),on=.(x,y),nomatch=0] #不匹配的行,不返回
##    x y v
## 1: b 1 1
DT[.("b",1:2),on=.(x,y),roll=Inf] #不匹配的行,返回前边行对应的值
##    x y v
## 1: b 1 1
## 2: b 2 1
DT[.("b",1:2),on=.(x,y),roll=-Inf] #不匹配的行,返回后边行对应的值
##    x y v
## 1: b 1 1
## 2: b 2 2
DT[.("b"),sum(v*y),on="x"] #提取x=="b"的行,计算v*y的值,然后求和
## [1] 25

1.9 综合以上所有技能

DT[x!="a",sum(v),by=x] #对照
##    x V1
## 1: b  6
## 2: c 24
DT[!"a",sum(v),by=.EACHI,on="x"] #结果同上,速度更快 .EACHI的意思就是对i中的每一个水平分组分组
##    x V1
## 1: b  6
## 2: c 24
DT[c("b","c"),sum(v),by=.EACHI,on=.(x)]
##    x V1
## 1: b  6
## 2: c 24

1.10 合并数据集

DT #原始数据集
##    x y v
## 1: b 1 1
## 2: b 3 2
## 3: b 6 3
## 4: a 1 4
## 5: a 3 5
## 6: a 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
X = data.table(x=c("c","b"),v=8:7,foo=c(4,2)) #X作为拟要合并的数据集
X
##    x v foo
## 1: c 8   4
## 2: b 7   2
X[DT,on="x"] #以DT数据集中x列为主,筛选与之匹配的X中的行,left join
##    x  v foo y i.v
## 1: b  7   2 1   1
## 2: b  7   2 3   2
## 3: b  7   2 6   3
## 4: a NA  NA 1   4
## 5: a NA  NA 3   5
## 6: a NA  NA 6   6
## 7: c  8   4 1   7
## 8: c  8   4 3   8
## 9: c  8   4 6   9
DT[X,on="x"] #以X数据集中x列为主,筛选与之匹配的DT行 right join
##    x y v i.v foo
## 1: c 1 7   8   4
## 2: c 3 8   8   4
## 3: c 6 9   8   4
## 4: b 1 1   7   2
## 5: b 3 2   7   2
## 6: b 6 3   7   2
DT[X,on="x",nomatch=0] #返回双方共有的行 inner join
##    x y v i.v foo
## 1: c 1 7   8   4
## 2: c 3 8   8   4
## 3: c 6 9   8   4
## 4: b 1 1   7   2
## 5: b 3 2   7   2
## 6: b 6 3   7   2
DT[!X,on="x"] #返回的是X中没有的DT数据集中的行
##    x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
DT[X,on=.(y<=foo)] #从此一下的表达式不是特别理解
##    x y v i.x i.v
## 1: b 4 1   c   8
## 2: b 4 2   c   8
## 3: a 4 4   c   8
## 4: a 4 5   c   8
## 5: c 4 7   c   8
## 6: c 4 8   c   8
## 7: b 2 1   b   7
## 8: a 2 4   b   7
## 9: c 2 7   b   7
DT[X,on=.(y>=foo)]
##    x y v i.x i.v
## 1: b 4 3   c   8
## 2: a 4 6   c   8
## 3: c 4 9   c   8
## 4: b 2 2   b   7
## 5: b 2 3   b   7
## 6: a 2 5   b   7
## 7: a 2 6   b   7
## 8: c 2 8   b   7
## 9: c 2 9   b   7
DT[X,on=.(x,y<=foo)]
##    x y v i.v
## 1: c 4 7   8
## 2: c 4 8   8
## 3: b 2 1   7
DT[X,.(x,y,x.y,v),on=.(x,y>foo)]
##    x y x.y v
## 1: c 4   6 9
## 2: b 2   3 2
## 3: b 2   6 3
DT[X,on="x",mult="first"]
##    x y v i.v foo
## 1: c 1 7   8   4
## 2: b 1 1   7   2
DT[X,on="x",mult="last"]
##    x y v i.v foo
## 1: c 6 9   8   4
## 2: b 6 3   7   2
DT[X,sum(v),by=.EACHI,on="x"]
##    x V1
## 1: c 24
## 2: b  6
DT[X,sum(v)*foo,by=.EACHI,on="x"]
##    x V1
## 1: c 96
## 2: b 12
DT[X,sum(v)*i.v,by=.EACHI,on="x"]
##    x  V1
## 1: c 192
## 2: b  42
DT[X, on=.(x, v>=v), sum(y)*foo, by=.EACHI]
##    x v V1
## 1: c 8 36
## 2: b 7 NA