强大的data.table包

在写《R中的apply簇函数》一文时同学王修坤推荐使用data.table包,他提出该包针对大批量数据和分组处理数据时会非常迅速。这几天研究了一下该包,确实觉得非常的伟大,下面从几个案例中说明该包的短、平、快特征。


在正式介绍data.table包之前,这里先模拟生成1000W行和7列的数据集,产生的csv文件有817M。脚本如下:

set.seed(1234)

x1 <- 1:10000000

x2 <- rnorm(10000000)

x3 <- rt(10000000,2)

x4 <- rf(10000000,2,3)

x5 <- rpois(10000000,5)

x6 <- sample(letters,10000000,replace = TRUE)

x7 <- rchisq(10000000,3)

my.df <- data.frame(x1 = x1, x2 = x2, x3 = x3,

x4 = x4, x5 = x5, x6 = x6,

x7 = x7)

write.csv(my.df, 'test.csv', row.names = FALSE)


一、读取数据

通过使用data.table包中的fread()函数可以快速的读取大数据集

案例对比:

#使用read.table()函数读取

system.time(read.table(file = file.choose(),

head = TRUE, sep = ','))

0?wx_fmt=jpeg
#使用read.csv()函数读取

system.time(read.csv(file = file.choose(),

head = TRUE, sep = ','))

0?wx_fmt=jpeg
#使用data.table包中的fread()函数读取

library(data.table)

system.time(fread(input = file.choose()))

0?wx_fmt=jpeg
从中可以看出,fread()函数在读取大文本文件时,速度上有显著的提升,要比read.table()快了近6倍,比read.csv()也快了近5倍。


二、数据排重

data.table包中与数据排重相关的有两个重要函数:

1)duplicated()函数返回数据行是否有重复的逻辑值,TRUE表示某行重复,FALSE表示某行不存在重复

2)unique()函数返回所有唯一的数据行

这两个函数可以灵活的指定某些列是否重复。

案例对比:排除数据集my.df中x5和x6两列的重复值

df <- my.df

dt <- data.table(my.df)

library(sqldf)

system.time(sqldf('select distinct x5,x6 from df'))

0?wx_fmt=jpeg
library(data.table)

system.time(unique(dt[,list(x5,x6)], by = c('x5','x6')))

0?wx_fmt=jpeg
同样的排重目的,read.table包中的unique函数比SQL快了近70倍


三、取子集

提取数据集的子集一般使用subset函数,但函数的参数x为数据框或data.table格式的数据时,其运算速度是存在差异的

案例对比:

system.time(subset(x = df, x2 >= 1 & x3 <= 0.5 & x6 == 'c' | x7 > 1.2))


system.time(subset(x = dt, x2 >= 1 & x3 <= 0.5 & x6 == 'c' | x7 > 1.2))

0?wx_fmt=jpeg
对1000W行的数据集,差异虽然不是很明显,但如果有更大的数据集的话,这种差异一定会显得非常明显。


四、排序

排序操作经常会碰到,但是数据量一大的话,性能往往会下降很多,如果使用data.table包中的setorder函数的话,速度会有一个明显的提升。

案例对比:

library(plyr)

system.time(arrange(my.df, x2, desc(x3), x6))


library(data.table)

system.time(setorder(dt, x2, -x3, x6))

0?wx_fmt=jpeg
通过使用plyr包中的arrange()函数和data.table包中的setorder()函数对比,发现后者比前者的速度快了123倍!


五、分组计算

一般对于明细数据都需要聚合操作,下面比较两种方式,就可以得知read.table包的速度了。

案例对比:

library(sqldf)

system.time(sqldf('select x6, avg(x1) A, min(x2) B,

max(x3) C ,max(x5)-min(x5) D

from df group by x6'))


library(data.table)

system.time(dt[, list(A = mean(x1), B = min(x2), C = max(x3),

D = diff(range(x5))), by = x6])

0?wx_fmt=jpeg
为达到同样的聚合效果,data.table包所显示的速度是另一种方法的72倍!


通过以上几个案例的对比分析,我们可以看见read.table包中的函数应用比较简单(代码较少)而且运行速度也是非常快速的。除此之外,该包中还包括重命名变量名函数setnames()、数据整形函数melt()和dcast()、数据合并函数merge()和rbind()、rbindlist()等。详细信息可以查看相应的帮助文件。


文中脚本可以到以下链接下载:

http://yunpan.cn/c39DJRpPZEFwU 访问密码 2932

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值