【发布时间】:2017-04-22 18:08:48
【问题描述】:
我经常发现自己在同一个数据表上使用:= 进行一系列链式计算。比如这样的
test = data.table(1:10, 1:10, 1:10, 1:10)
test[, V1 := V1^2]
test[, V2 := V1*V2]
test[, V3 := V2/V3]
test[, V4 := sqrt(V3)]
test[, new := letters[V4]]
必须在每一行写test[, ...] 1) 需要更长的时间来输入(这不是我能应付的大问题)。但是,更重要的是,这也会在视觉上分散计算的流程和内容。我宁愿写类似的东西
test[, {
V1 := V1^2
V2 := V1*V2
V3 := V2/V3
V4 := sqrt(V3)
new := letters[V4]
}]
但这会引发You have wrapped := with {} which is ok but then := must be the only thing inside {} 的错误。
我知道我会写
within(test, {
V1 = V1^2
V2 = V1*V2
V3 = V2/V3
V4 = sqrt(V3)
new = letters[V4]
})
但这失去了使用:=的效率
我尝试编写一个函数来提供这种能力
with.dt = function(dt, expressions){
e = strsplit(expressions,'\n')
for (i in 1:length(e)){
dt[, eval(parse(text = e[i]))]
}
dt
}
with.dt(test, "
V1 := V1^2;
V2 := V1*V2;
V3 := V2/V3;
V4 := sqrt(V3);
new := letters[V4];
")
但这不会改变data.table的内容
是否有任何语法允许within 版本的整洁外观,同时保留:= 的引用分配属性?
【问题讨论】:
-
如果您不需要按顺序完成它们,您可以执行以下操作:
test[,:=(v1 = v1^2, v2 = v1*v2)]:=周围应该有反引号 -
扩展 Kristoferson 所说的内容,我认为您可以使用
DT[, `:=`(V1 = V1 <- 10, V2 = V2 <- V1^2, ...)]之类的 hack 按顺序进行操作 -
@Frank 感谢您的建议。我使用
with.dt的函数定义再次尝试更新了 q。知道为什么这不起作用吗? -
@clemlaflemme data.table 和
:=的特点之一是通过引用修改对象,因此您无需重新分配结果。 -
@Kristofersen 我花了很长时间才意识到这一点,但是您可以通过反斜杠在内联代码块中转义 cmets 中的反引号:
\`将保持原样:`:=`
标签: r data.table colon-equals