【发布时间】:2016-06-10 07:19:56
【问题描述】:
我有一个很大的(1200 万行)data.table,看起来像这样:
library(data.table)
set.seed(123)
dt <- data.table(id=rep(1:3, each=5),y=sample(letters[1:5],15,replace = T))
> dt
id y
1: 1 b
2: 1 d
3: 1 c
4: 1 e
5: 1 e
6: 2 a
7: 2 c
8: 2 e
9: 2 c
10: 2 c
11: 3 e
12: 3 c
13: 3 d
14: 3 c
15: 3 a
我想创建一个新的data.table,其中包含我的变量id(这将是这个新data.table的唯一键)和其他5个二进制变量,每个变量对应于y的每个类别,它们取值1 如果 id 具有 y 的值,则 0 否则。
输出 data.table 应如下所示:
id a b c d e
1: 1 0 1 1 1 1
2: 2 1 0 1 0 1
3: 3 1 0 1 1 1
我尝试在循环中执行此操作,但速度很慢,而且我不知道如何以编程方式传递二进制变量名称,因为它们取决于我试图“拆分”的变量。
编辑:正如@mtoto 指出的那样,here 已经提出并回答了类似的问题,但解决方案是使用reshape2 包。
我想知道是否有另一种(更快的)方法可以使用 data.table 中的 := 运算符,因为我有一个庞大的数据集,并且我正在使用这个包进行很多工作。
EDIT2:@Arun 帖子中关于我的数据的函数基准测试(约 1200 万行、约 350 万个不同的 id 和 490 个不同的标签,用于y 变量(结果为 490虚拟变量)):
system.time(ans1 <- AnsFunction()) # 194s
system.time(ans2 <- dcastFunction()) # 55s
system.time(ans3 <- TableFunction()) # Takes forever and blocked my PC
【问题讨论】:
-
我注意到有类似的行,例如四和五,你能解释一下这个数据吗?据我了解
data[1][e]=1 if(2>0) else 0但这似乎有点奇怪。 -
@kpie 我编辑了第二个
data.table,现在应该更清楚了:idn.1 具有y的不同值b,c,d,e,但不是a。这就解释了为什么他在第二个data.table上的行除了a列之外的所有地方都有1。 @mtoto 感谢您的回答,这将解决我的问题,但是有了如此庞大的数据,我想知道是否有另一种方法可以在data.table内部做同样的事情,也许是:=运算符。 -
如果你想使用
data.table,你可以使用dcast():dcast(dt, id ~ y,fun.aggregate = function(x) (length(x) > 0)+0) -
你也可以考虑将你的 1/0 放在一个“矩阵”中,可能是稀疏的以节省一些内存——
uy = unique(dt$y); m = matrix(0L, max(dt$id), length(uy), dimnames = list(NULL, uy)); m[cbind(dt$id, match(dt$y, uy))] = 1L
标签: r data.table binary-data programmatically-created