I am trying to develop a function which will calculate the means, standard error, and confidence intervals of some survey data. I need to do this repeatedly over a number of different variables with a bunch of different filter statements.
DATA
df <- data.frame(address_id = rep(c(1,1,1,2,2,2,3,3,3,4,4,4),5),
person_id = rep(c(1,2,3),20),
sex = as.factor(rep(c("male","female"),30)),
response_var = as.factor(rep(seq(1,6,1))),
weight = runif(60, 50, 200))
Example that works without function
# create survey design
design <- survey::svydesign(data = df,
strata = ~ address_id,
id = ~ person_id,
nest = TRUE,
weights = ~ weight)
# calcualte weighted mean
mean_se <- survey::svymean(~sex, design)
# calculate confidence intervals
ci <- survey::confint(df_mean)
My function
create_mean_and_cis <- function(data, var){
design <- survey::svydesign(data = data,
strata = ~ address_id,
id = ~ person_id,
nest = TRUE,
weights = ~ weight)
mean_se <- survey::svymean(~{{var}}, design)
ci <- confint(mean_se)%>%
tibble::as_tibble()%>%
tibble::rownames_to_column("variable")
output <- mean_se%>%
tibble::as_tibble()%>%
tibble::rownames_to_column("variable")%>%
dplyr::left_join(ci)
return(output)
}
# function call
create_mean_and_cis(sex)
When I run, I get an error message saying:
Error in survey::svydesign(data = data, strata = ~address_id, id = ~person_id, :
object 'sex' not found
I can't understand what is going wrong. The tidy evaluation works perfectly when I use the curly-curly "{{var}}" within other functions. Why doesn't it work here? Can anyone help?
I have tried several variations of quasiquotation including: !!enquo(sex), sym(sex), !!sym(sex), {{sex}}, eval(parse(sex)). None of which have yielded working results.
If you wanted to use more advanced tidy evaulation features, you can use rlang::eval_tidy
mean_se <- rlang::eval_tidy(rlang::quo(survey::svymean(~{{var}}, design)))
You wrap your expression in a quosure where you can use the {{ }}
and !!
style syntax. Both quo
and eval_tidy
will recognize this syntax. These features are unique to functions that use the rlang
package; you cannot use them directly any arbitrary R function without some sort of rlang
wrapper.
Or per @Lionel's suggestion, you can use rlang::inject
to build the formula and pass that to svymean
formula <- rlang::inject(~!!substitute(var))
mean_se <- survey::svymean(formula, design)