- 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