在准引用上下文之外取消引用 quosure
Unquote quosure outside quasiquotation context
我正在定义一个函数来获取回归模型的预测值,其中包含不同子组(子群体)的调查数据。我使用调查包中的 svyglm 函数。
我的问题涉及处理 svyglm 函数中的子集选项。因为它使用非标准评估,我理解这意味着它不会将列名作为字符串。我尝试只使用不带字符串的列名称并引用 (enquo) 和取消引用 (!!)。但是,这两个选项都不起作用。我也玩过 ensym() 和 expr() 但没有得到任何结果。
数据与图书馆
library(dplyr)
library(survey)
library(srvyr)
library(purrr)
library(rlang)
mtcars <- read.table("https://forge.scilab.org/index.php/p/rdataset/source/file/master/csv/datasets/mtcars.csv",
sep=",", header=TRUE)
mtcars_cplx <- mtcars %>% as_survey_design(id = cyl, weights = qsec)
carb <- c(1:8)
cyl <- c(4:8)
new_data <- expand.grid(carb, cyl)
colnames(new_data) <- c("carb", "cyl")
有问题
函数和输入
subpop_pred <- function(formula, data, subpop, new_data) {
subpop_quo <- enquo(subpop)
subpop_txt <- data$variables %>% select(!!subpop_quo) %>% colnames()
for(i in min(data$variables[subpop_txt]):max(data$variables[subpop_txt])){
reg <- svyglm(formula, data, subset=!!subpop_quo==i)
pred <- predict(reg, newdata=new_data)
if(exists("reg_end")==TRUE){
pred <- cbind(new_data, pred, confint(pred))
pred[subpop_txt] <- i
reg_end <- rbind(reg_end, pred)
} else {
reg_end <- cbind(new_data, pred, confint(pred))
reg_end[subpop_txt] <- i
}
}
}
subpop_pred(mpg ~ carb + cyl + carb*cyl,
data=mtcars_cplx,
new_data=new_data,
subpop=gear)
Output/Error
Error: Base operators are not defined for quosures.
Do you need to unquote the quosure?
# Bad:
myquosure == rhs
# Good:
!!myquosure == rhs
Call `rlang::last_error()` to see a backtrace
8. stop(cnd)
7. abort(paste_line("Base operators are not defined for quosures.",
"Do you need to unquote the quosure?", "", " # Bad:", bad,
"", " # Good:", good, ))
6. Ops.quosure(subpop_quo, i)
5. eval(subset, model.frame(design), parent.frame())
4. eval(subset, model.frame(design), parent.frame())
3. svyglm.survey.design(formula, data, subset = !!subpop_quo ==
i)
2. svyglm(formula, data, subset = !!subpop_quo == i)
1. subpop_pred(mpg ~ carb + cyl + carb * cyl, data = mtcars_cplx,
new_data = new_data, subpop = gear)
没有问题
函数和输入
subpop_pred <- function(formula, data, subpop, new_data) {
subpop_quo <- enquo(subpop)
subpop_txt <- data$variables %>% select(!!subpop_quo) %>% colnames()
for(i in min(data$variables[subpop_txt]):max(data$variables[subpop_txt])){
reg <- svyglm(formula, data, subset=subpop==i)
pred <- predict(reg, newdata=new_data)
if(exists("reg_end")==TRUE){
pred <- cbind(new_data, pred, confint(pred))
pred[subpop_txt] <- i
reg_end <- rbind(reg_end, pred)
} else {
reg_end <- cbind(new_data, pred, confint(pred))
reg_end[subpop_txt] <- i
}
}
}
subpop_pred(mpg ~ carb + cyl + carb*cyl, data=mtcars_cplx, new_data=new_data, subpop=gear)
输出
Error in eval(subset, model.frame(design), parent.frame()) :
object 'gear' not found
5. eval(subset, model.frame(design), parent.frame())
4. eval(subset, model.frame(design), parent.frame())
3. svyglm.survey.design(formula, data, subset = subpop == i)
2. svyglm(formula, data, subset = subpop == i)
1. subpop_pred(mpg ~ carb + cyl + carb * cyl, data = mtcars_cplx,
new_data = new_data, subpop = gear)
您知道如何让该功能发挥作用吗?
不确定是否有更好的方法,因为 svyby()
似乎不支持 svyglm()
。这里,quo_squash()
用于将表达式传递给 subset()
。
这可以扩展到做预测。
gears = unique(mtcars$gear)
lapply(gears, function(x) {
subset(mtcars_cplx, !!quo_squash(gear == x)) %>%
svyglm(mpg ~ carb + cyl + carb*cyl, design = .)
})
我可以通过混合使用 expr()
和 rlang::tidy_eval()
来使用 subset
参数。
函数中的模型行可以是:
reg <- svyglm(formula, data = data,
subset = rlang::eval_tidy( expr( !!subpop_quo == i), data = data) )
不过,我不知道这是否可靠,或者是否有更直接的 tidyeval 方法。致力于此让我意识到 subset()
function/argument 很难在函数中使用。 :-P
我正在定义一个函数来获取回归模型的预测值,其中包含不同子组(子群体)的调查数据。我使用调查包中的 svyglm 函数。
我的问题涉及处理 svyglm 函数中的子集选项。因为它使用非标准评估,我理解这意味着它不会将列名作为字符串。我尝试只使用不带字符串的列名称并引用 (enquo) 和取消引用 (!!)。但是,这两个选项都不起作用。我也玩过 ensym() 和 expr() 但没有得到任何结果。
数据与图书馆
library(dplyr)
library(survey)
library(srvyr)
library(purrr)
library(rlang)
mtcars <- read.table("https://forge.scilab.org/index.php/p/rdataset/source/file/master/csv/datasets/mtcars.csv",
sep=",", header=TRUE)
mtcars_cplx <- mtcars %>% as_survey_design(id = cyl, weights = qsec)
carb <- c(1:8)
cyl <- c(4:8)
new_data <- expand.grid(carb, cyl)
colnames(new_data) <- c("carb", "cyl")
有问题
函数和输入
subpop_pred <- function(formula, data, subpop, new_data) {
subpop_quo <- enquo(subpop)
subpop_txt <- data$variables %>% select(!!subpop_quo) %>% colnames()
for(i in min(data$variables[subpop_txt]):max(data$variables[subpop_txt])){
reg <- svyglm(formula, data, subset=!!subpop_quo==i)
pred <- predict(reg, newdata=new_data)
if(exists("reg_end")==TRUE){
pred <- cbind(new_data, pred, confint(pred))
pred[subpop_txt] <- i
reg_end <- rbind(reg_end, pred)
} else {
reg_end <- cbind(new_data, pred, confint(pred))
reg_end[subpop_txt] <- i
}
}
}
subpop_pred(mpg ~ carb + cyl + carb*cyl,
data=mtcars_cplx,
new_data=new_data,
subpop=gear)
Output/Error
Error: Base operators are not defined for quosures.
Do you need to unquote the quosure?
# Bad:
myquosure == rhs
# Good:
!!myquosure == rhs
Call `rlang::last_error()` to see a backtrace
8. stop(cnd)
7. abort(paste_line("Base operators are not defined for quosures.",
"Do you need to unquote the quosure?", "", " # Bad:", bad,
"", " # Good:", good, ))
6. Ops.quosure(subpop_quo, i)
5. eval(subset, model.frame(design), parent.frame())
4. eval(subset, model.frame(design), parent.frame())
3. svyglm.survey.design(formula, data, subset = !!subpop_quo ==
i)
2. svyglm(formula, data, subset = !!subpop_quo == i)
1. subpop_pred(mpg ~ carb + cyl + carb * cyl, data = mtcars_cplx,
new_data = new_data, subpop = gear)
没有问题
函数和输入
subpop_pred <- function(formula, data, subpop, new_data) {
subpop_quo <- enquo(subpop)
subpop_txt <- data$variables %>% select(!!subpop_quo) %>% colnames()
for(i in min(data$variables[subpop_txt]):max(data$variables[subpop_txt])){
reg <- svyglm(formula, data, subset=subpop==i)
pred <- predict(reg, newdata=new_data)
if(exists("reg_end")==TRUE){
pred <- cbind(new_data, pred, confint(pred))
pred[subpop_txt] <- i
reg_end <- rbind(reg_end, pred)
} else {
reg_end <- cbind(new_data, pred, confint(pred))
reg_end[subpop_txt] <- i
}
}
}
subpop_pred(mpg ~ carb + cyl + carb*cyl, data=mtcars_cplx, new_data=new_data, subpop=gear)
输出
Error in eval(subset, model.frame(design), parent.frame()) :
object 'gear' not found
5. eval(subset, model.frame(design), parent.frame())
4. eval(subset, model.frame(design), parent.frame())
3. svyglm.survey.design(formula, data, subset = subpop == i)
2. svyglm(formula, data, subset = subpop == i)
1. subpop_pred(mpg ~ carb + cyl + carb * cyl, data = mtcars_cplx,
new_data = new_data, subpop = gear)
您知道如何让该功能发挥作用吗?
不确定是否有更好的方法,因为 svyby()
似乎不支持 svyglm()
。这里,quo_squash()
用于将表达式传递给 subset()
。
这可以扩展到做预测。
gears = unique(mtcars$gear)
lapply(gears, function(x) {
subset(mtcars_cplx, !!quo_squash(gear == x)) %>%
svyglm(mpg ~ carb + cyl + carb*cyl, design = .)
})
我可以通过混合使用 expr()
和 rlang::tidy_eval()
来使用 subset
参数。
函数中的模型行可以是:
reg <- svyglm(formula, data = data,
subset = rlang::eval_tidy( expr( !!subpop_quo == i), data = data) )
不过,我不知道这是否可靠,或者是否有更直接的 tidyeval 方法。致力于此让我意识到 subset()
function/argument 很难在函数中使用。 :-P