在j data.table中使用函数而不是{}

时间:2015-06-16 16:39:59

标签: r data.table

你能帮我理解为什么在data.table中我可以在{}中按名称访问列,例如

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

但在功能中不能做同样的事情

test_sum <- function() {
   list(z = x + y)
}
dt[, test_sum()]

这与https://stackoverflow.com/a/19958647/3021252相同吗?

如果是这样,那么拥有像

这样的功能会更好
test_sum2 <- function(data) {
   list(z = data$x + data$y)
}
dt[, test_sum2(.SD)]

test_sum3 <- function(x, y) {
   list(z = x + y)
}
dt[, test_sum3(x, y)]

2 个答案:

答案 0 :(得分:2)

我认为你最后的选择是最好的。你的第一个选择 - 没有任何参数只是不好的做法,因为读者不清楚函数内部/神奇地使用外部数据(假设你使它工作)。第二种选择更好,但你传递了太多信息。您的最终选项会传递完全正确的信息量,这与data.table一起使用,因为它不必在计算中提供其他列。

至于为什么选项不起作用,只是因为data.table只提供它检测到的{{1}}环境中的那些列(通过做一个简单的文本)解析表达式,在本例中为{{1}},不使用任何列。)

答案 1 :(得分:0)

我不太确定你为什么要这样做,特别是在阅读链接的问题之后。理论上你可以这样做:

test_sum <- function() quote(list(z = x + y))
dt[, eval(test_sum)]

但正如链接的答案所说,一旦开始使用by,您可能会遇到问题。

列应该在data.table调用中真正定义,因此更好的方法是:

test_sum <- function(a, b) a + b
dt[, list(z = test_sum(x, y))]

或上面的test_sum3

我认为您将大括号混淆为代表匿名函数。它们表示一个表达式,该表达式将在当前范围内执行。有关eval和quote等内容的更多信息,请参阅Hadley Wickham's excellent chapter on non-standard evaluation