为什么“替代”可以多行工作,而不是单行工作? [英] Why does `substitute` work in multiple lines, but not in a single line?

查看:91
本文介绍了为什么“替代”可以多行工作,而不是单行工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图回答这个很好的问题有关为data.table对象创建非标准评估函数的问题,进行分组总和。 Akrun提出了一个可爱的答案,我将在这里简化:

I was attempting to answer this nice question about creating a non-standard evaluating function for a data.table object, doing a grouped sum. Akrun came up with a lovely answer which I'll simplify here:

akrun <- function(data, var, group){
 var <- substitute(var)
 group <- substitute(group)
 data[, sum(eval(var)), by = group]
}

library(data.table)
mt = as.data.table(mtcars)
akrun(mt, cyl, mpg)
#    group    V1
# 1:     6 138.2
# 2:     4 293.3
# 3:     8 211.4

我也在研究一个答案,并且得到了几乎相同的答案,但是替代与其他内容保持一致。我的导致错误:

I was also working on an answer, and had close to the same answer, but with the substitutes inline with the rest. Mine results in an error:

gregor = function(data, var, group) {
  data[, sum(eval(substitute(var))), by = substitute(group)]
} 

gregor(mt, mpg, cyl)
# Error in `[.data.table`(data, , sum(eval(substitute(var))), by = substitute(group)) : 
#  'by' or 'keyby' must evaluate to vector or list of vectors 
#  (where 'list' includes data.table and data.frame which are lists, too) 

,我的功能是Akrun的简单替代。为什么它不起作用?

At its face, my function is a simple substitution of Akrun's. Why doesn't it work?

请注意,两个替换都会导致问题,如下所示:

Note that both substitutions cause problems, as shown here:

gregor_1 = function(data, var, group) {
  var = substitute(var)
  data[,sum(eval(var)), 
       by = substitute(group)]
} 
gregor_1(mt, mpg, cyl)
# Same error as above


gregor_2 = function(data, var, group) {
  group = substitute(group)
  data[,sum(eval(substitute(var))), 
       by = group]
} 
gregor_2(mt, mpg, cyl)
# Error in eval(substitute(var)) : object 'mpg' not found 


推荐答案

替代的文档中,您可以了解其内容决定要替换的内容
以及默认情况下它将搜索调用它的环境的事实。
如果您在 data.table 框架
中调用替代(即在<$ c内部$ c> [] )
,因为它们没有出现在 data.table 中,所以找不到符号评估环境,
它们位于调用 [的环境中。

In substitute's documentation you can read how it decides what to substitute, and the fact that, by default, it searches the environment where it is called. If you call substitute inside the data.table frame (i.e. inside []) it won't be able to find the symbols because they are not present inside the data.table evaluation environment, they are in the environment where [ was called.

您可以反转调用函数的顺序以便获得所需的行为:

You can "invert" the order in which the functions are called in order to get the behavior you want:

library(data.table)

foo <- function(dt, group, var) {
    eval(substitute(dt[, sum(var), by = group]))
}

foo(as.data.table(mtcars), cyl, mpg)
   cyl    V1
1:   6 138.2
2:   4 293.3
3:   8 211.4

这篇关于为什么“替代”可以多行工作,而不是单行工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆