R语言data.table简介
data.table包提供了一个非常简洁的通用格式:DT[i,j,by],可以理解为:对于数据集DT,选取子集行i,通过by分组计算j,对比与dplyr等包,data.table的运行速度更快。
创建一个data.table
set.seed(1)
DF = data.frame(x=c("b","b","b","a","a"),v=rnorm(5))
DF
## x v
## 1 b -0.6264538
## 2 b 0.1836433
## 3 b -0.8356286
## 4 a 1.5952808
## 5 a 0.3295078
这跟data.frame的创建是一样的
DT = data.table(x=c("b","b","b","a","a"),v=rnorm(5))
DT
## x v
## 1: b -0.8204684
## 2: b 0.4874291
## 3: b 0.7383247
## 4: a 0.5757814
## 5: a -0.3053884
或者可以直接将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
我们可以使用tables()
函数查看所有在内存的data.table
tables()
## NAME NROW NCOL MB COLS KEY
## [1,] CARS 50 2 1 speed,dist
## [2,] DT 5 2 1 x,v
## Total: 2MB
1. Keys
Keys在data.table中是一个重要的概念,在一个data.table中只能设置一个key,但是这一个key可以包含多个列。当我们设置好key后,data.table会将数据按照key来排序。
DT[2,] #取第2行
## x v
## 1: b 0.4874291
DT[x=="b",] #取x=b的行
## x v
## 1: b -0.8204684
## 2: b 0.4874291
## 3: b 0.7383247
cat(try(DT["b",],silent=TRUE))
## 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.
当没有设置key时,DT[“b”]操作会报以上错误,我们可以用setkey()
给DT设置key
setkey(DT,x)
DT["b",]
DT["b"] #更简洁的写法
## x v
## 1: b -0.8204684
## 2: b 0.4874291
## 3: b 0.7383247
默认情况下会返回该分组的所有元素mult='all'
,但是如果我们想要其他结果,比如返回第一个元素,或返回最后一个元素
DT["b",mult="first"]
## x v
## 1: b -0.8204684
DT["b",mult="last"]
## x v
## 1: b 0.7383247
接下下我们创建一个1000万行的数据,用来演示data.table的性能
grpsize = ceiling(1e7/26^2) # 10 million rows, 676 groups
tt=system.time( DF <- data.frame(x=rep(LETTERS,each=26*grpsize),y=rep(letters,each=grpsize),v=runif(grpsize*26^2),stringsAsFactors=FALSE))
head(DF,3)
## x y v
## 1 A a 0.9347052
## 2 A a 0.2121425
## 3 A a 0.6516738
tail(DF,3)
## x y v
## 10000066 Z z 0.9537745
## 10000067 Z z 0.6654964
## 10000068 Z z 0.9368095
dim(DF)
## [1] 10000068 3
我们试试将DF中x为“R”的行与y为”h”的行提取出来
system.time(ans1 <- DF[DF$x=="R" & DF$y=="h",])
## user system elapsed
## 1.35 0.07 1.42
head(ans1,3)
## x y v
## 6642058 R h 0.2442074
## 6642059 R h 0.6491902
## 6642060 R h 0.5894140
我们使用data.table做相同的操作:
DT = as.data.table(DF)
system.time(setkey(DT,x,y))
## user system elapsed
## 0.13 0.01 0.14
system.time(ans2 <- DT[list("R","h")])
## user system elapsed
## 0.02 0.00 0.02
可以看到,当我们设置好key后,提取行的操作基本不需要等待时间,比我们平时用的操作快了100倍。要注意的是,如果使用”==”操作符,那么它会扫描整个数组,虽然data.table用这种方法也可以提取,但很慢,要尽量避免。
system.time(ans1 <- DT[x=="R" & y=="h"]) # works but is using data.table badly
## user system elapsed
## 1.06 0.00 1.06
2. 快速聚合(fast grouping)
接下来我们要介绍data.table的第二个参数
DT[,sum(v)]
## [1] 4999770
head(DT[,sum(v),by=x])
## x V1
## 1: A 192270.6
## 2: B 192261.3
## 3: C 192292.2
## 4: D 191924.2
## 5: E 192457.3
## 6: F 192240.2
以上代码以x为分组,依次调用sum函数,统计了每个分组x的总和。显然这一功能在plyr包和dplyr包也有相对应的函数实现,接下来我们比较一下这3个包的速度。
#plyr包
system.time(ddply(DF,.(x),function(x)sum(x$v)))
## user system elapsed
## 1.71 0.22 1.94
#dplyr包
system.time({DF%>%group_by(x)%>%summarise(sum(v))
})
## user system elapsed
## 0.60 0.12 0.72
#data.table包
DT = as.data.table(DF)
system.time({
DT[,sum(v),by=x]
})
## user system elapsed
## 0.12 0.02 0.14
从以上结果中很明显看到data.table远远快于dplyr和plyr包
3. 快速连接
使用DT[X],该操作会将X中key(没指定key则默认第一列)与DT的key作连接,同理,X[DT]会将DT与X作连接
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
DT
## x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3
## 4: b 1 4
## 5: b 3 5
## 6: b 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
X = data.table(c("b","c"),foo=c(4,2))
X
## V1 foo
## 1: b 4
## 2: c 2
setkey(DT,x)
DT[X]
## x y v foo
## 1: b 1 4 4
## 2: b 3 5 4
## 3: b 6 6 4
## 4: c 1 7 2
## 5: c 3 8 2
## 6: c 6 9 2
setkey(X,V1)
X[DT]
## V1 foo y v
## 1: a NA 1 1
## 2: a NA 3 2
## 3: a NA 6 3
## 4: b 4 1 4
## 5: b 4 3 5
## 6: b 4 6 6
## 7: c 2 1 7
## 8: c 2 3 8
## 9: c 2 6 9
我们也可以使用on操作来连接两个相同的列:
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
X = data.table(x=c("b","c"),foo=c(4,2))
DT[X, on="x"] # join on columns 'x'
## x y v foo
## 1: b 1 4 4
## 2: b 3 5 4
## 3: b 6 6 4
## 4: c 1 7 2
## 5: c 3 8 2
## 6: c 6 9 2
我们也可以使用data.table中的merge函数
(dt1 <- data.table(A = letters[1:10], X = 1:10, key = "A"))
## A X
## 1: a 1
## 2: b 2
## 3: c 3
## 4: d 4
## 5: e 5
## 6: f 6
## 7: g 7
## 8: h 8
## 9: i 9
## 10: j 10
(dt2 <- data.table(A = letters[5:14], Y = 1:10, key = "A"))
## A Y
## 1: e 1
## 2: f 2
## 3: g 3
## 4: h 4
## 5: i 5
## 6: j 6
## 7: k 7
## 8: l 8
## 9: m 9
## 10: n 10
merge(dt1, dt2)
## A X Y
## 1: e 5 1
## 2: f 6 2
## 3: g 7 3
## 4: h 8 4
## 5: i 9 5
## 6: j 10 6
作为分享主义者(sharism),本人所有互联网发布的图文均遵从CC版权,转载请保留作者信息并注明作者a358463121专栏:http://blog.csdn.net/a358463121,如果涉及源代码请注明GitHub地址:https://github.com/358463121/。商业使用请联系作者。
R语言data.table简介相关推荐
- R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象
R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象 目录 R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象 #data.t ...
- R语言data.table导入数据实战:把data.frame数据转化为data.table数据
R语言data.table导入数据实战:把data.frame数据转化为data.table数据 目录 R语言data.table导入数据实战:把data.frame数据转化为data.table数据 ...
- R语言data.table导入数据实战:data.table使用by函数进行数据分组(aggregate)
R语言data.table导入数据实战:data.table使用by函数进行数据分组(aggregate) 目录 R语言data.table导入数据实战:data.table使用by函数进行数据分组( ...
- R语言data.table进行滚动数据连接,滚动连接通常用于分析涉及时间的数据(例如商业销售活动和对应的广告投放的安排之之间的关系)实战:实战和动画说明滚动数据连接的形式及方法
R语言data.table进行滚动数据连接,滚动连接通常用于分析涉及时间的数据(例如商业销售活动和对应的广告投放的安排之之间的关系)实战:实战和动画说明滚动数据连接的形式及方法 目录
- R语言data.table进行滚动数据连接,滚动联接通常用于分析涉及时间的数据实战(动画说明滚动数据连接的形式):rolling joins data.table in R
R语言data.table进行滚动数据连接,滚动联接通常用于分析涉及时间的数据实战(动画说明滚动数据连接的形式):rolling joins data.table in R 目录
- R语言data.table导入数据实战:data.table生成新的数据列(基于已有数据列)、生成多个数据列
R语言data.table导入数据实战:data.table生成新的数据列(基于已有数据列).生成多个数据列 目录 R语言data.table导入数据实战:data.
- R语言data.table导入数据实战:data.table使用字符向量创建新的数据列
R语言data.table导入数据实战:data.table使用字符向量创建新的数据列 目录 R语言data.table导入数据实战:data.table使用字符向量创建新的数据列
- R语言data.table详解
@R语言学习 data.table用法解析 R语言中的data.table是一种数据处理时的高效率工具.在了解data.table之前先简单说明一下管道函数的使用方法. 管道函数的使用方法 常用的管道 ...
- R之data.table速查手册
R语言data.table速查手册 介绍 R中的data.table包提供了一个data.frame的高级版本,让你的程序做数据整型的运算速度大大的增加.data.table已经在金融,基因工程学等领 ...
最新文章
- 百度:2020年十大科技趋势
- 135.137.138.139.445端口分析
- python 预编译命令_Python子进程调用预编译j
- android动态更改布局宽高,动态更改Android上的线性布局宽度或高度
- mysql5.7重新初始化_MySQl 5.7 初始化方式变更
- 开源神器!答应我,别再用 abc 做变量名了好么!
- 在Windows 下如何使用 AspNetCore Api 和 consul
- php 正则提取url,php 正则表达式提取网页超级链接url的函数
- 金额数字转中文大写(转)
- 3月份Github上最热门的Python开源项目
- listview中有按钮、图片等需要不同点击处理的控件如何处理
- Hive 数据质量检测
- log4j2配置文件
- 相对地址转化为绝对地址
- javascript 数组操作函数
- linux 查看安装软件
- 机器学习中的数学——激活函数(一):Sigmoid函数
- android4.2.2飞歌导航,智能车机新典范 飞歌G6S荣耀版导航鉴赏
- android studio拼音转汉字,汉字转拼音,TinyPinyin、Pinyin4j与JPinyin哪个库更快
- VS2008 水晶报表部署