在data.table中组合多个变量名列表?

时间:2015-05-05 19:51:33

标签: r data.table

我正在尝试将两个单独的变量名列表传递给data.table(v1.9.4)。它返回正确的列,但它会删除变量名称。这按预期工作:

dt <- data.table(a=1:3, b=4:6, c=7:9, d=10:12)
dt
   a b c  d
1: 1 4 7 10
2: 2 5 8 11
3: 3 6 9 12

它也适用于传递一个名单列表:

dt[,list(a,b)]
   a b
1: 1 4
2: 2 5
3: 3 6

但是当我需要传递多个列表时,它会返回正确的列,但会删除变量名称:

dt[,c(list(a,b), list(c,d))]
   V1 V2 V3 V4
1:  1  4  7 10
2:  2  5  8 11
3:  3  6  9 12

为什么有两个名单?我正在使用多个quote()'d变量列表。我已经阅读了FAQ问题1.6,我知道一个解决方法是使用带有= FALSE的字符向量。但是我的真实用例涉及将名称和表达式的混合传递给函数,例如,

varnames <- quote(list(a,b))
expr <- quote(list(a*b, c+d))
function(dt, varnames, expr) {
  dt[,c(varnames, expr)]
}

我希望“varnames”列有他们的专有名称(如果你只是传递一个列表,他们会这样做

dt[,list(a,b,a*b,c+d)]
   a b V3 V4
1: 1 4  4 17
2: 2 5 10 19
3: 3 6 18 21

如何在data.table中组合多个列表,以便它仍然返回正确的列名? (我不完全确定这是否是一个data.table问题,或者我只是在尝试在R中组合列表的方式做一些愚蠢的事情,但c()似乎做了我想做的事。)< / p>

2 个答案:

答案 0 :(得分:4)

另一种选择是提前构建完整的呼叫:

varnames[4:5] <- expr[2:3]  # this results in `list(a, b, a * b, c + d)`
dt[, eval(varnames)]

产生

   a b V3 V4
1: 1 4  4 17
2: 2 5 10 19
3: 3 6 18 21

更一般地说,假设您有一个引用的表达式列表列表:

exprlist <- list(quote(list(a, b)), quote(list(c, c %% a)), quote(list(a + b)))
expr <-  as.call(Reduce(function(x, y) c(as.list(x), as.list(y)[-1]), exprlist))  # @eddi
dt[, eval(expr)]

答案 1 :(得分:1)

以下是使用.SD

的可能解决方法
varnames <- quote(list(a,b))
expr <- quote(list(a*b, c+d))

myFunc <- function(dt, varnames, expr) {
  dt[, c(.SD[, eval(varnames)], eval(expr))]
}

myFunc(dt, varnames, expr)

#    a b V1 V2
# 1: 1 4  4 17
# 2: 2 5 10 19
# 3: 3 6 18 21