我想在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))
col <- colnames(DT)
DT[, out := sum(col), by = 1:nrow(DT)]
编辑:
David Arenburg的回答DT[, out := Reduce(
+ , .SD), .SDcols = col]
适用于此特定情况。但我真的不明白这种方法如何应用于另一个函数调用。我编写了以下函数进行测试:
myfun <- function(x, y, ...){
in.tmp1 <- x
in.tmp2 <- c(y, ...)
out.tmp <- in.tmp1 + mean(in.tmp2)
return(out.tmp)
}
同样,明确写下列名称可以使用以下方法:
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)]
但我无法为其列名指定的data.table中的大型子集制定更通用的解决方案。
答案 0 :(得分:0)
请考虑以下事项:
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)]
这里我们收集my_vars
到var_list
中的一组任意列,这是dt
中相应列的未复制别名列表。可以使用do.call
将列作为R中函数的参数传递,但参数列表中的元素名称(此处为var_list
)必须与函数的参数名称匹配( myfun
有args“x”,“y”和“...”,但最后一个是任意名称的元素。)
如果您想更多地使用data.table
而不使用mget
,请尝试
## 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]
编辑2017-02-22:在do.call
中也允许使用未命名的列。
dt[, "out" := do.call(myfun, unname(as.list(.SD))), .SDcols = my_vars]