当扩展数据表时出现奇怪的错误

3

我们在尝试扩展data.table时发现了一些奇怪的行为。 下面的代码可以正常工作:

dt <- data.table(var1=1:2e3, var2=1:2e3, freq=1:2e3)
system.time(dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")])
##    user  system elapsed 
##    0.05    0.01    0.06

但是使用以下的data.table
set.seed(1)
dt <- data.table(var1=sample(letters,1000,replace=T),var2=sample(LETTERS,1000,replace=T),freq=sample(1:10,1000,replace=T))

使用相同的代码

可以得到
Error in rep(1, freq) : invalid 'times' argument

我的问题
这可能是data.table中的一个bug吗?

(我从R机器学习基础中获取了这个示例的语法)

编辑
所以问题似乎真正出在rep上,而不是data.tablerep的帮助页面对于参数times说:

如果长度为length(x),则给出一个整数向量,表示重复每个元素的次数(非负),或者如果长度为1,则重复整个向量。

第二个data.table创建的timesx的长度不同,这导致了错误。


我没有错误。你使用的R和R Studio版本是什么? - Mike Wise
我正在使用的R版本是3.1.3,RStudio版本是0.99.447。 - Mike Wise
是的,我在data.table 1.9.4和R 3.2.0中看到了相同的错误。 - Frank
2
很奇怪,我没有任何错误。 - Mike Wise
@MikeWise 你确定按照描述运行了代码(根据第二位制作“dt”,然后重新运行“system.time”)吗?我怀疑“rep”一直都是这样工作的。 - Frank
显示剩余7条评论
1个回答

6
我猜测:当rep(x,times)times参数为向量时,它会强制要求x的长度与之相同(而不是在R中自然地循环)。因此手动循环可以解决这个问题。
dt[ ,.(rep(rep(1,.N),freq)), by=.(var1,var2)]

似乎是基础R中存在问题(或者可能是故意的?),而不是data.table中的问题。在第一个示例中,OP没有遇到这个问题,因为by = .(var1,var2)确保每个组仅返回一行,因此times参数是标量。

那么 by 子句与此有什么关系? - vonjd
@vonjd 的 by 子句确保了 times 是一个标量而不是向量。我会将其添加到答案中。 - Frank
在R中技术上没有标量,只有长度为1的向量...仍然没有完全理解问题 :-( - vonjd
我使用“标量”作为长度为1的向量的简称,是的。 - Frank
@vonjd 尝试使用 dt[,.N,by=.(var1,var2)][,table(N)] 命令来查看 dt 中不同分组的大小。如果它们中有任何一个不等于 1,则会抛出错误。 - Frank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接