【问题标题】:How to use data.table inside a function?如何在函数中使用 data.table?
【发布时间】:2014-05-28 11:10:55
【问题描述】:

作为一个最小的工作示例,例如,我希望能够动态地将表达式传递给 data.table 对象以创建新列或修改现有列:

dt <- data.table(x = 1, y = 2)
dynamicDT <- function(...) {
    dt[, list(...)]
}
dynamicDT(z = x + y)

我期待:

   z
1: 3

但是,我得到了错误:

Error in eval(expr, envir, enclos) : object 'x' not found 

那么我该如何解决这个问题?

尝试:

我见过this post,它建议使用quotesubstitute,但是

> dynamicDT(z = quote(x + y))
Error in `rownames<-`(`*tmp*`, value = paste(format(rn, right = TRUE),  : 
  length of 'dimnames' [1] not equal to array extent

> dynamicDT <- function(...) {
+     dt[, list(substitute(...))]
+ }
> dynamicDT(z = x + y)
Error in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L,  : 
  first argument must be atomic

对我没用。

【问题讨论】:

  • 如果您使用list,您将无法获得所需的输出。如果你的函数可以工作,输出将是z 1: 3。你需要使用:=
  • @DavidArenburg。感谢您指出这一点 - 是写作时的疏忽。现已修复。
  • 我其实为你原来想要的输出写了一个答案,你还需要吗
  • 当然 - 谢谢大卫。调整最终输出应该不会太难。重要的是您如何设法传递要在 data.table 上下文中评估的表达式,而不是 .GlobalEnv
  • 查看我对多个变量的编辑

标签: r data.table


【解决方案1】:

这应该是大卫回答的更好选择:

dynamicDT <- function(...) {
 dt[, eval(substitute(...))]
}

dynamicDT(z := x + y)
#   x y z
#1: 1 2 3

【讨论】:

  • (+1) 不错的@Roland,当然更好
  • 谢谢 - 这可以处理多个参数,例如dynamicDT(a := x + y, b := x - y)
  • 它仍然必须是正确的 data.table 语法。有关语法,请参阅 David 的答案。
【解决方案2】:

您需要使用eval(parse(text = )) 组合。 parse 会将字符串转换为表达式,而eval 将评估它。

library(data.table)
dt <- data.table(x = 1, y = 2)
dynamicDT <- function(temp = "") {
  dt[, eval(parse(text = temp))]
}

为了得到你之前想要的输出

dynamicDT("z := x + y")
##    x y z
## 1: 1 2 3

为了得到你当前想要的输出

dynamicDT("z = x + y")
## [1] 3

为了解析多个参数,您可以这样做

dynamicDT('c("a","b") := list(x + y, x - y)')

##   x y a  b
##1: 1 2 3 -1

【讨论】:

    猜你喜欢
    • 2017-07-11
    • 2021-06-07
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 2016-08-19
    • 2017-10-11
    相关资源
    最近更新 更多