msp*_*msp 41 r data.table
data.table
是一个梦幻般的R包,我在我正在开发的库中使用它.到目前为止,一切都很顺利,除了一个并发症.data.table
使用保存在变量中的名称来引用列(例如:对于数据帧),似乎要比使用常规数据帧更难(与传统数据帧相比colname="col"; df[df[,colname]<5,colname]=0
).
也许最让事情变得复杂的是这种语法明显缺乏一致性data.table
.在某些情况下,eval(colname)
和get(colname)
,甚至c(colname)
似乎工作.在其他方面,DT[,colname, with=F]
是解决方案.然而在其他方面,例如,set()
和subset()
功能,我根本没有找到解决方案.最后,前面讨论了一个极端的,虽然也是非常常见的用例(以编程方式将列名称传递给data.table),并且建议的解决方案虽然显然正在完成他们的工作,但似乎并不特别可读......
也许我太复杂了?如果有人可以记下快速备忘单,以便data.table
使用不同常见场景的变量来引用列名,我将非常感激.
更新:
提供的一些具体示例我可以硬编码列名:
x.short = subset(x, abs(dist)<=100)
set(x, which(x$val<10), "val", 0)
Run Code Online (Sandbox Code Playgroud)
现在假设distcol="dist"
,valcol="val"
.使用distcol
and valcol
,但不是dist
和val
?的最佳方法是什么?
edd*_*ddi 26
如果你要在j
表达式中进行复杂的操作,你应该使用eval
和quote
.当前版本的一个问题data.table
是环境eval
并不总是正确处理 - 在data.table中引用eval和引用(注意:根据对软件包的更新,对该答案进行了更新.) - 以及当前版本修补程序是添加.SD
到eval
.据我所知,从一些测试我已经运行这不会影响速度(例如.SD[1]
,j
如果有的话).
有趣的是这个问题只困扰了j
,你会使用被罚款eval
在正常i
(其中.SD
不可反正).
另一个问题是赋值,你必须有字符串.我知道一种从引用的表达式中提取字符串名称的方法 - 它不漂亮,但它有效.这是一个将所有内容组合在一起的示例:
x = data.table(dist = c(1:10), val = c(1:10))
distcol = quote(dist)
valcol = quote(val)
x[eval(valcol) < 5,
capture.output(str(distcol, give.head = F)) := eval(distcol)*sum(eval(distcol, .SD))]
Run Code Online (Sandbox Code Playgroud)
注意我是如何不添加.SD
一个eval(distcol)
,但如果我从另一个中取出它将不会eval
.
另一种选择是使用get
:
diststr = "dist"
valstr = "val"
x[get(valstr) < 5, c(diststr) := get(diststr)*sum(get(diststr))]
Run Code Online (Sandbox Code Playgroud)
也许你已经知道这个解决方案?
DT[[colname]]
Run Code Online (Sandbox Code Playgroud)
这是受@ eddi在下面评论中的解决方案的启发,使用OP的例子:
set.seed(1)
x = data.table(a = 1:10, b=rnorm(10))
colstr="b"
col <- eval(parse(text=paste("quote(",colstr,")",sep="")))
x[eval(col)<0]
x[eval(col)<0,c(colstr):=-100]
Run Code Online (Sandbox Code Playgroud)