R data.table:通过引用为赋值使用colname

R data.table:通过引用为赋值使用colname,r,data.table,R,Data.table,我想在data.table中使用列名作为引用赋值(:=)。调用的函数正在对几列中的每行执行一些计算。我使用data.table(v1.9.7)的当前开发版本,这使得参数“with=TRUE”不必要 具有显式变量名的运行示例如下: DT <- data.table(a = 1:10, b = seq(2, 20, 2), c = seq(5, 50, 5)) DT[, out := sum(a, b), by = 1:nrow(DT)] 同样,使用以下方法显式编写列名也很有效: DT &l

我想在data.table中使用列名作为引用赋值(:=)。调用的函数正在对几列中的每行执行一些计算。我使用data.table(v1.9.7)的当前开发版本,这使得参数“with=TRUE”不必要

具有显式变量名的运行示例如下:

DT <- data.table(a = 1:10, b = seq(2, 20, 2), c = seq(5, 50, 5))
DT[, out := sum(a, b), by = 1:nrow(DT)]
同样,使用以下方法显式编写列名也很有效:

DT <- data.table(a = 1:10, b = seq(2, 20, 2), c = seq(5, 50, 5))
DT[, out := myfun(a,b,c), by = 1:nrow(DT)]

DT考虑以下几点:

library("data.table")

dt <- data.table(a = 1:5, b = 5:1, c = 1, d = 2, e = 5:1)


myfun <- function(x, y, ...){
  in.tmp1 <- x
  in.tmp2 <- c(y, ...)
  out.tmp <- in.tmp1 + mean(in.tmp2)
  return(out.tmp)
}

my_vars <- c("a", "c", "d")

var_list <- mget(my_vars, envir = as.environment(dt))

names(var_list)[1:2] <- c("x", "y")

dt[, "out" := do.call(myfun, var_list)]
编辑2017-02-22:在
do.call
中也允许使用未命名列

dt[, "out" := do.call(myfun, unname(as.list(.SD))), .SDcols = my_vars]

如果你在做
by=1:nrow(DT)
你做错了。我将使用
DT[,out:=Reduce(`+`,.SD),.SDcols=col]
谢谢,这确实有效。但这是否也适用于其他函数(例如,mean)或自己编写的函数?通过对这个问题的回答,我得到了
by=1:nrow(DT)
的想法。在我的第一个例子中,它确实按预期工作。就像eddi说的,向量化更好。这取决于功能。您将使用
by=1:nrow(DT)
的唯一情况是绝对没有其他选择。无论是R还是
数据。表
都是按行设计的,而不是按列/矩阵设计的。同样,这取决于你的功能。另外,如果您的数据集很小,我想按行工作也没什么大不了的。我发现在考虑按行操作时,这个Q&a(以及其中的链接)非常有用:谢谢大家,但我仍然没有在data.table中调用具有许多参数的函数。我认为问题在于引用。我试着根据这个答案使用
col,非常感谢!你的解决方案肯定有效。然而,在我看来,使用
data.table
并不是预期的方法。但我也可能错了。@moe我不确定你所说的预期方法是什么意思,但对于更多的“data.table-like”代码,你可以试试我在帖子中添加的代码块。由于
do.call
尝试通过列的名称将列与函数参数相匹配,另一种解决方案是在传递给
do.call的列表中根本没有任何名称。但是,这假设列的顺序正确。
library("data.table")

dt <- data.table(a = 1:5, b = 5:1, c = 1, d = 2, e = 5:1)


myfun <- function(x, y, ...){
  in.tmp1 <- x
  in.tmp2 <- c(y, ...)
  out.tmp <- in.tmp1 + mean(in.tmp2)
  return(out.tmp)
}

my_vars <- c("a", "c", "d")

var_list <- mget(my_vars, envir = as.environment(dt))

names(var_list)[1:2] <- c("x", "y")

dt[, "out" := do.call(myfun, var_list)]
## so myfun finds the correct columns for args "x" and "y"
setnames(dt, c("a", "c"), c("x", "y"))

my_vars <- c("x", "y", "d")
dt[, "out" := do.call(myfun, .SD), .SDcols = my_vars]
dt[, "out" := do.call(myfun, unname(as.list(.SD))), .SDcols = my_vars]