tidyeval 取消引用用户创建的变量以供后续使用

tidyeval unquote user created variable for subsequent usage

我无法取消引用由函数创建的变量(如果重要的话带有前缀)以便稍后在函数中使用。 enquo 似乎不起作用,但我确定我在做一些愚蠢的事情。 (我是 tidyeval 的新手。

library(survey)
library(ggplot2)
library(dplyr)

data(api)

names( apistrat)
apistrat <- apistrat %>% as_survey_design(ids = 1, fpc = fpc)

test_func <- function(var) {
  apistrat %>% mutate(col.grad=as.factor(col.grad)) %>% group_by(col.grad) %>% 
    summarise("mean_{{var}}" := survey_mean({{ var }}, na.rm=TRUE)) %>% 
    mutate("ub_mean_{{var}}" :=
             "mean_{{var}}_se" * 1.96 + "mean_{{var}}") #Think I need to unquote for this line so it's evaluated
}
test_func(meals)

#Tried this, which didn't work
test_func <- function(var) {
  apistrat %>% mutate(col.grad=as.factor(col.grad)) %>% group_by(col.grad) %>% 
    summarise("mean_{{var}}" := survey_mean({{ var }}, na.rm=TRUE)) %>% 
    mutate("ub_mean_{{var}}" :=
             enquo("mean_{{var}}_se") * 1.96 + enquo("mean_{{var}}")) #Think I need to unquote for this line so it's evaluated
}
test_func(meals)

#Desired output
test_func <- function(var) {
  apistrat %>% mutate(col.grad=as.factor(col.grad)) %>% group_by(col.grad) %>% 
    summarise("mean_{{var}}" := survey_mean({{ var }}, na.rm=TRUE)) 
}
test_func(meals) %>% mutate(ub_mean_meals=mean_meals_se*1.96+mean_meals) #Want this part in the function


挑战是想要操作变量名,最好使用字符串算术而不是表达式算术。一种方法是创建一个包装器,将符号转换为字符串,将它们拼接在一起,然后将结果转换回符号:

library( tidyverse )
lbl <- function(...) {ensyms(...) %>% reduce(str_c) %>% sym}

然后您可以使用此包装器即时创建新标签:

test_func <- function(var) {
    L1 <- lbl( mean_, {{var}} )
    L2 <- lbl( mean_, {{var}}, `_se` )
    L3 <- lbl( ub_mean_, {{var}} )

    apistrat %>% mutate(col.grad=as.factor(col.grad)) %>% group_by(col.grad) %>%
        summarise( !!L1 := survey_mean({{ var }}, na.rm=TRUE)) %>%
        mutate( !!L3 := !!L2 * 1.96 + !!L1 )
}

test_func(meals)
# # A tibble: 48 x 4
#    col.grad mean_meals mean_meals_se ub_mean_meals
#    <fct>         <dbl>         <dbl>         <dbl>
#  1 0              51.5         7.71           66.6
#  2 2              96           0.916          97.8
#  3 3              83.9         6.45           96.6
#  4 4              96           2.77          101.
# ...