【发布时间】:2015-09-06 18:03:58
【问题描述】:
我发现有关 data.table 中特定列名的一些尖锐边缘。我怎样才能避免在他们身上割伤自己?假设我有一个包含两列“类型”和“值”的 data.table。
numRows = 100
numTypes = 10
dt = data.table(type=sample(numTypes, numRows, replace=T),
value=rnorm(numRows))
如果我想快速计算 type==3 的所有行的平均值,这很好用:
dt[type==3, mean(value)]
# [1] 0.08086124
但是如果“不是我的人”出现并认为“类型”对于该列来说是一个糟糕的名称,而它真的应该是一个“类”呢?
setnames(dt, "type", "class")
现在,当我尝试等效操作时,我会收到可怕的错误消息:
dt[class==3, mean(value)]
# Error in setattr(attr(x, "index"), paste(cols, collapse = "__"), o) :
# attempt to set invalid 'class' attribute
这是预期的行为(对于 OSX 上的 1.9.4)?我认为它的发生是因为“类”是 R 中的一个函数名,而 data.table 内部的一些东西正在解释它。将 i 子句括在括号中似乎可以解决问题:
dt[(class==3), mean(value)]
# [1] 0.08086124
但也许在某些情况下这种解决方法也会失败?
在这种情况下,是否存在预期会失败的列名列表?
用户定义的函数或加载的库会导致同样的错误吗?
一般来说,我应该使用一种更安全的方法吗?
【问题讨论】:
-
它看起来像 1.9.4 中的一个熟悉的错误。升级或在其周围加上括号,例如
dt[(class==3), mean(value)]。顺便说一句,如果你可以让你的例子只用几行,你为什么不呢?如果一定要去100,请记得使用set.seed。 -
对不起,如果示例太大。我在回答我打开的另一个问题的过程中遇到了这个问题(看起来你刚刚迁移到 Stats?)。我不认为 100 是一个很大的数字,因为我刚刚将它从 1000000 中删除。不知道你为什么建议 set.seed --- 行数与种子的选择有什么关系?还是您的观点(正确)是在没有 set.seed() 的情况下,确切的数字是不可重现的?
-
“正确”?是啊谢谢。在这种情况下,
set.seed的意义在于,人们可以确认达到了预期的结果。通过“你为什么不呢?”我的意思是提醒您,SO 上最好使用最少的示例...并且可以想到在这种情况下的一个原因:如果您的示例足够小,则可以将其作为问题的一部分打印出来,从而使读者更快掌握你正在做什么和试图做什么。嘿,反正我就是这么做的;继续按照你自己的判断。
标签: r data.table reserved-words