gpt4 book ai didi

r - 为什么 `substitute` 在多行工作,而不是在单行工作?

转载 作者:行者123 更新时间:2023-12-04 11:55:52 24 4
gpt4 key购买 nike

我试图回答 this nice question关于为 data.table 对象创建非标准评估函数,进行分组求和。 Akrun 想出了一个可爱的答案,我将在这里简化:

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

我也在研究一个答案,并且得到了接近相同的答案,但使用 substitute与其余部分内联。我的结果是一个错误:
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 的简单替代。为什么它不起作用?

请注意,这两种替换都会导致问题,如下所示:
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

最佳答案

看来substitute不能在数据表中以人们期望的方式在其他上下文中工作,但您可以使用 enexpr从 rlang 包代替 substitute :

library(data.table)
library(rlang)

gregor_rlang = function(data, var, group) {
data[, sum(eval(enexpr(var))), by = .(group = eval(enexpr(group)))]
}

gregor_rlang(mt, mpg, cyl)
## group V1
## 1: 6 138.2
## 2: 4 293.3
## 3: 8 211.4

环境

这个问题似乎与环境有关,因为这适用于我们专门给定环境 substitute 的环境。应该使用。
gregor_pf = function(data, val, group) {
data[, sum(eval(substitute(val, parent.env(environment())))),
by = c(deparse(substitute(group)))]
}
gregor_pf(mt, mpg, cyl)
## cyl V1
## 1: 6 138.2
## 2: 4 293.3
## 3: 8 211.4

关于r - 为什么 `substitute` 在多行工作,而不是在单行工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58649510/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com