【问题标题】:Alternative to (m)get in data.table functions在 data.table 函数中替代 (m)get
【发布时间】:2020-02-23 19:42:18
【问题描述】:

假设我有以下 data.table 并希望通过引用存储在向量中的变量来获得以下输出:

dt <- data.table(a = rep(1, 3),
                 b = rep(2, 3))

x <- 'a'
y <- 'b'

dt[, .(sum(get(x)), mean(get(y)))]

   V1 V2
1:  3  2

很酷,它有效。但现在我想做一个函数,然后做类似的事情:

foo <- function(arg1, arg2) {

  dt[, .(sum(get(arg1)), mean(get(arg2)))]

}

foo(x, y)

意识到它有效,我想避免打电话给所有gets,并做类似的事情:

foo <- function(arg1, arg2) {

  eval(substitute(dt[, .(sum(arg1), mean(arg2))]))

}

foo(x, y) # or foo('x', 'y')

但这失败了。关于如何以类似于多次调用get 的方式一次评估所有参数的任何想法?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    我们可以用as.symbolas.nameevaluate转换成symbol

    foo <- function(arg1, arg2) {
    
        dt[, .(sum(eval(as.name(arg1))), mean(eval(as.name(arg2))))]
    
     }
    
    foo(x, y)
    #   V1 V2
    #1:  3  2
    

    或者使用[[对data.table的列进行子集化

    foo <- function(arg1, arg2) {
    
      dt[, .(sum(.SD[[arg1]]), mean(.SD[[arg2]]))]
    
     }
    
    foo(x, y)
    #   V1 V2
    #1:  3  2
    

    或者另一种选择是pasteeval/parse

     foo <- function(arg1, arg2) {
    
         eval(parse(text = paste0("dt[, .(sum(", arg1, "), mean(", arg2, "))]")))
    
       }
    
    foo(x, y)
    #   V1 V2
    #1:  3  2
    

    【讨论】:

    • 谢谢!这可行,但我仍然需要重复eval.SD。我会看看那里是否有其他答案,如果没有,我会接受。
    【解决方案2】:

    不确定这是否是您要查找的内容,另一种选择是在调用 substitute 之前强制进行 as.name 转换:

    foo <- function(arg1, arg2) {
        A1 <- as.name(arg1);
        A2 <- as.name(arg2);
        eval(substitute(dt[, .(sum(A1), mean(A2))]))
    }
    
    dt <- data.table(a = rep(1, 3), b = rep(2, 3))
    foo('a' 'b')
    

    输出:

       V1 V2
    1:  3  2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多