【发布时间】:2017-10-24 10:14:12
【问题描述】:
我正在使用美妙的 R data.table 包。但是,使用变量名访问(即通过引用操作)列是非常笨拙的:如果给定一个 data.table dt,它有两列 x 和 y,我们想要添加两列并将其命名为 z,那么命令是
dt = dt[, z := x + y]
现在让我们编写一个函数add,它接受一个(引用a)data.table dt 和三个列名summand1Name、summand2Name 和resultName 作为参数,它应该执行与上面完全相同的命令,仅具有通用列名。我现在使用的解决方案是反射,即
add = function(dt, summand1Name, summand2Name, resultName) {
cmd = paste0('dt = dt[, ', resultName, ' := ', summand1Name, ' + ', summand2Name, ']')
eval(parse(text=cmd))
return(dt) # optional since manipulated by reference
}
但是我对这个解决方案绝对不满意。首先,它很笨拙,这样编写代码并不有趣。调试起来很困难,而且只会让我生气并浪费时间。其次,它更难阅读和理解。这是我的问题:
我们可以用更好的方式编写这个函数吗?
我知道人们可以访问具有变量名称的列,如下所示:dt[[resultName]] 但是当我写的时候
dt[[resultName]] = dt[[summand1Name]] + dt[[summand2Name]]
然后 data.table 开始抱怨已复制并且无法通过引用工作。我不想要那个。我也喜欢dt = dt[<all 'database related operations'>] 的语法,这样我所做的一切都被放在一对括号中。是不是可以使用反引号之类的特殊符号来表示当前使用的名称不是引用数据表的实际列,而是实际列名称的占位符?
【问题讨论】:
-
你应该看看
get和mget -
另见this
-
add = function(dt, summand1Name, summand2Name, resultName) dt[, (resultName) := .SD[[summand1Name]] + .SD[[summand2Name]]]怎么样?另一个选项可能是add2 = function(dt, summand1Name, summand2Name, resultName) dt[, (resultName) := eval(as.name(summand1Name)) + eval(as.name(summand2Name))]或只使用上面建议的get。
标签: r data.table