data.table包简介
2016-02-09 11:38
204 查看
data.table包简介
junjun
2016年2月9日
参考:http://blog.163.com/yugao1986@126/blog/static/6922850820145305014187
data.table包简介
data.table包主要特色是:设置keys、快速分组和滚得时序的快速合并。data.table主要通过二元检索法大大提高数据操作的效率,同时它也兼容适用于data.frame的向量检索法。#1、加载data.table包并创建数据 library(data.table)
## Warning: package 'data.table' was built under R version 3.2.3
#类似于data.frame数据的创建,使用data.table函数 (DF = data.frame(x=c("b","b","b","a","a"), v=rnorm(5)))
## x v ## 1 b 2.6018532 ## 2 b 1.3779741 ## 3 b 0.1936382 ## 4 a -1.7746176 ## 5 a -0.1412760
(DT = data.table(x=c("b","b","b","a","a"), v=rnorm(5)))
## x v ## 1: b -0.9180313 ## 2: b 1.5366401 ## 3: b 0.2097379 ## 4: a -0.2030940 ## 5: a 0.6819083
#可以看出,DF和DT的行号有一些区别,这也是data.frame和data.table主要区别。 #利用data.frame创建data.table: CARS <- data.table(cars) head(CARS)
## speed dist ## 1: 4 2 ## 2: 4 10 ## 3: 7 4 ## 4: 7 22 ## 5: 8 16 ## 6: 9 10
#已经创建了两个data.table数据,tables命令可以显示该信息: tables()
## NAME NROW NCOL MB COLS KEY ## [1,] CARS 50 2 1 speed,dist ## [2,] DT 5 2 1 x,v ## Total: 2MB
#其中"MB"列可以快速评估内存使用,发现删除可以释放内存的表格。 #查看表中数据类型 sapply(DT, class)
## x v ## "character" "numeric"
#2、键Keys #类似人的姓名有“姓”和“名”组成,data.table中的Keys可以由多个部分组成,Keys的组成部分可以使整数、因子、字符串或其他格式,而且data.table中的每行数据是按照Keys排序的,所以data.table数据最多只有一个Key. #DT和CARS是data.table格式,当前没有设置任何Keys,我们可以使用适用于数据框data.frame的语法: DT[2, ]
## x v ## 1: b 1.53664
DT[DT$x=="b", ]
## x v ## 1: b -0.9180313 ## 2: b 1.5366401 ## 3: b 0.2097379
#由于DT没有行名称,所以下面的命令不能正常运行: cat(try(DT["b", ], silent = T))
## Error in `[.data.table`(DT, "b", ) : ## When i is a data.table (or character vector), x must be keyed (i.e. sorted, and, marked as sorted) so data.table knows which columns to join to and take advantage of x being sorted. Call setkey(x,...) first, see ?setkey.
#报错信息显示,我们需要对data.table数据设置keys setkey(DT, x) #此时,DT已经按照x值进行了重新排序,如果要确认一个data.table数据是否有keys,我们可以使用haskey()、key()、attributes()或者tables()函数。 tables()
## NAME NROW NCOL MB COLS KEY ## [1,] CARS 50 2 1 speed,dist ## [2,] DT 5 2 1 x,v x ## Total: 2MB
#现在,DT数据已经拥有Key:x,我们尝试列出所有x=b的数据 DT["b", mult="first"]
## x v ## 1: b -0.9180313
DT["b", mult="last"]
## x v ## 1: b 0.2097379
#3、下面创建一个足够大的数据来说明“向量检索法”和“二元检索法”的效率差异 ##10000068行,676个分组的数据DF grpsize <- ceiling(1e7/26^2) tt <- system.time(DF <- data.frame( x=rep(LETTERS,each=26*grpsize), y=rep(letters,each=grpsize), v=runif(grpsize*26^2), stringsAsFactors=FALSE )) tt
## user system elapsed ## 0.71 0.03 0.75
head(DF, 3)
## x y v ## 1 A a 0.6166219 ## 2 A a 0.8981881 ## 3 A a 0.5288605
tail(DF, 3)
## x y v ## 10000066 Z z 0.01418355 ## 10000067 Z z 0.14773928 ## 10000068 Z z 0.04807132
dim(DF)
## [1] 10000068 3
#下面我们从DF中剥离其中任意一组 #1)'向量检索法' (tt <- system.time(ans1 <- DF[DF$x=="R" & DF$y=="h", ]))
## user system elapsed ## 0.85 0.05 0.89
head(ans1, 3)
## x y v ## 6642058 R h 0.2144749 ## 6642059 R h 0.3516665 ## 6642060 R h 0.7069858
dim(ans1)
## [1] 14793 3
#2)'二元检索法' DT <- as.data.table(DF) #一次性遍历所有元素时间 system.time(setkey(DT, x, y))
## user system elapsed ## 0.08 0.00 0.08
#二元条件检索 (ss <- system.time(ans2 <- DT[J("R", "h")]))
## user system elapsed ## 0 0 0
head(ans2, 3)
## x y v ## 1: R h 0.2144749 ## 2: R h 0.3516665 ## 3: R h 0.7069858
dim(ans2)
## [1] 14793 3
identical(ans1$v,ans2$v)
## [1] TRUE
#可以看出使用二元检索法较向量检索法,效率上要高很多。 #4、data.table也支持向量检索,但这样的话效率会低很多,我们应尽量避免这种情况。例如: #1)低效的data.table用法 system.time(ans1 <- DT[x=="R" & y=="h",])
## user system elapsed ## 0.62 0.00 0.62
#2)data.frame用法 system.time(ans2 <- DF[DF$x=="R" & DF$y=="h",])
## user system elapsed ## 0.72 0.05 0.77
mapply(identical,ans1,ans2)
## x y v ## TRUE TRUE TRUE
#上例中,当使用DT$x==“R"时候,就会使用”向量检索法“遍历数据的整列,y=="h"同样,最后再使用”&“合并两个条件。data.table包提供了J()函数用于数据合并,可以大大提高效率。 identical( DT[J("R","h"), ], DT[data.table("R","h"), ])
## [1] TRUE
#5、快速分组 #1)对于data.table,使用”[i, j]“进行二元检索,我们可以接"by"进行分组计算 DT[, sum(v), by=x]
## x V1 ## 1: A 192354.6 ## 2: B 192247.6 ## 3: C 192292.0 ## 4: D 192264.5 ## 5: E 192288.5 ## 6: F 192220.6 ## 7: G 192395.2 ## 8: H 192222.0 ## 9: I 192040.1 ## 10: J 192310.9 ## 11: K 192260.1 ## 12: L 192304.8 ## 13: M 192153.6 ## 14: N 191912.4 ## 15: O 192417.9 ## 16: P 192633.6 ## 17: Q 192184.2 ## 18: R 192329.8 ## 19: S 192318.8 ## 20: T 192192.2 ## 21: U 192036.3 ## 22: V 192267.9 ## 23: W 192242.6 ## 24: X 192354.4 ## 25: Y 192666.8 ## 26: Z 192172.9 ## x V1
#该种方法相当高效,下面我们将其与tapply函数进行对比 (ttt <- system.time(tt <- tapply(DT$v, DT$x, sum)))
## user system elapsed ## 0.95 0.17 1.12
(sss <- system.time(ss <- DT[, sum(v), by=x]))
## user system elapsed ## 0.1 0.0 0.1
head(tt)
## A B C D E F ## 192354.6 192247.6 192292.0 192264.5 192288.5 192220.6
head(ss)
## x V1 ## 1: A 192354.6 ## 2: B 192247.6 ## 3: C 192292.0 ## 4: D 192264.5 ## 5: E 192288.5 ## 6: F 192220.6
identical(as.vector(tt), ss$V1)
## [1] TRUE
#下面我们按两列进行分组,比较两种方法的效率 (ttt=system.time(tt <- tapply(DT$v,list(DT$x,DT$y),sum)))
## user system elapsed ## 1.17 0.27 1.44
(sss=system.time(ss <- DT[,sum(v),by="x,y"]))
## user system elapsed ## 0.11 0.00 0.11
tt[1:5, 1:5]
## a b c d e ## A 7452.168 7337.349 7346.136 7358.049 7364.880 ## B 7416.583 7428.418 7386.688 7343.408 7427.261 ## C 7327.265 7440.357 7375.328 7363.778 7389.635 ## D 7375.853 7381.372 7409.695 7405.020 7406.129 ## E 7372.986 7418.662 7376.146 7390.650 7356.680
head(ss)
## x y V1 ## 1: A a 7452.168 ## 2: A b 7337.349 ## 3: A c 7346.136 ## 4: A d 7358.049 ## 5: A e 7364.880 ## 6: A f 7407.672
identical(as.vector(t(tt)), ss$V1)
## [1] TRUE
相关文章推荐
- 注解,多线程
- 方言APP应用方言说使用指南
- 吊扇项目总结(四)— LCX24G无线模块
- YTU 2507: 李白打酒
- NLP系列(5)_从朴素贝叶斯到N-gram语言模型
- 吊扇项目总结(三)— 嵌入式软件架构MVC模式
- NLP系列(5)_从朴素贝叶斯到N-gram语言模型
- YTU 2506: 切面条
- [从头学数学] 第77节 可能性
- Dsniff and Arpspoof on Mac
- nmap
- 设计模式之门面模式
- BloomFilter——大规模数据处理利器
- 个人学习-java-this关键字使用
- easyui-datagrid 报错:TypeError: col is null
- [原创][LaTex]LaTex学习笔记之框架及宏包
- cocos2d-x通过jni实现c++和java互调
- 数据类型检测
- Android 布局(fill_content、wrap_content、match_parent)
- cocos2d-x与安卓混编实现“更换头像”