将未加引号的字符参数列表的列表传递给 apply/map/pmap 调用
Pass a list of lists of unquoted character parameters to an apply/map/pmap call
我创建了一个函数来进行某种类型的分析:
library(tidyverse)
library(mediation)
causal_med_so <- function(predictor, mediator, outcome, data, ...){
if(!missing(...)) {
data <- {{data}} %>%
dplyr::select({{predictor}}, {{mediator}}, {{outcome}}, ...) %>%
dplyr::filter(across(.cols = everything(), .fns = ~ !is.na(.)))
predictor <- enquo(predictor)
mediator <- enquo(mediator)
outcome <- enquo(outcome)
med.form <- formula(paste0(
quo_name(mediator), "~",
paste0(
quo_name(predictor), "+",
paste0(c(...), collapse = "+"),
collapse = "+"
)
))
med.fit <- eval(bquote(lm(.(med.form), data = data)))
out.form <- formula(paste0(quo_name(outcome), "~",
paste0(
quo_name(predictor), "+",
quo_name(mediator), "+",
paste0(c(...), collapse = "+"),
collapse = "+"
)))
out.fit <- eval(bquote(lm(.(out.form), data = data)))
med.out <- mediation::mediate(med.fit, out.fit,
treat = quo_name(predictor),
mediator = quo_name(mediator),
boot=T, boot.ci.type = "bca")
return(med.out)
} else {
data <- {{data}} %>%
dplyr::select({{predictor}}, {{mediator}}, {{outcome}}) %>%
dplyr::filter(across(.cols = everything(), .fns = ~ !is.na(.)))
predictor <- enquo(predictor)
mediator <- enquo(mediator)
outcome <- enquo(outcome)
med.form <- formula(paste0(quo_name(mediator), "~", quo_name(predictor)))
med.fit <- eval(bquote(lm(.(med.form), data = data)))
out.form <- formula(paste0(quo_name(outcome), "~",
quo_name(predictor), "+", quo_name(mediator)))
out.fit <- eval(bquote(lm(.(out.form), data = data)))
med.out <- mediation::mediate(med.fit, out.fit,
treat = quo_name(predictor),
mediator = quo_name(mediator),
boot=T, boot.ci.type = "bca")
return(med.out)
}
}
函数似乎按预期运行:
causal_med_so(mpg, cyl, qsec, mtcars)
我现在想在 apply/map/pmap 调用中使用此函数,以所有可能的组合一次调用 运行 许多模型:
param_list <- list(
predictor = c("mpg", "cyl"),
mediator = c("drat", "disp", "wt", "cyl"),
outcome = c("qsec", "gear", "carb", "hp"),
data = c("mtcars")
) %>%
cross()
我正在尝试做这样的事情:
lmap(param_list, causal_med_so)
lapply(param_list, causal_med_so)
但是我遇到了一些错误消息,提示列表元素被视为字符。我尝试了 noquote()
、syms()
、!!!syms()
的几种组合,但似乎无法找到解决方案。
因为这些是字符串,所以最好转换为 sym
bol 并计算 (!!
)(为了测试,只使用 'param_dat' 的前两行(更改为 cross
到 cross_df
从而 return a tibble
)
causal_med_so <- function(predictor, mediator, outcome, data, ...){
predictor <- rlang::ensym(predictor)
mediator <- rlang::ensym(mediator)
outcome <- rlang::ensym(outcome)
if(!missing(...)) {
data <- get(data, envir = .GlobalEnv) %>%
dplyr::select(!!predictor, !!mediator, !!outcome, ...) %>%
dplyr::filter(across(.cols = everything(), .fns = ~ !is.na(.)))
predictor <- enquo(predictor)
mediator <- enquo(mediator)
outcome <- enquo(outcome)
med.form <- formula(paste0(
quo_name(mediator), "~",
paste0(
quo_name(predictor), "+",
paste0(c(...), collapse = "+"),
collapse = "+"
)
))
med.fit <- eval(bquote(lm(.(med.form), data = data)))
out.form <- formula(paste0(quo_name(outcome), "~",
paste0(
quo_name(predictor), "+",
quo_name(mediator), "+",
paste0(c(...), collapse = "+"),
collapse = "+"
)))
out.fit <- eval(bquote(lm(.(out.form), data = data)))
med.out <- mediation::mediate(med.fit, out.fit,
treat = quo_name(predictor),
mediator = quo_name(mediator),
boot=T, boot.ci.type = "bca")
return(med.out)
} else {
data <- get(data, envir = .GlobalEnv) %>%
dplyr::select(!!predictor, !!mediator, !!outcome) %>%
dplyr::filter(across(.cols = everything(), .fns = ~ !is.na(.)))
med.form <- formula(paste0(quo_name(mediator), "~", quo_name(predictor)))
med.fit <- eval(bquote(lm(.(med.form), data = data)))
out.form <- formula(paste0(quo_name(outcome), "~",
quo_name(predictor), "+", quo_name(mediator)))
out.fit <- eval(bquote(lm(.(out.form), data = data)))
med.out <- mediation::mediate(med.fit, out.fit,
treat = quo_name(predictor),
mediator = quo_name(mediator),
boot=T, boot.ci.type = "bca")
return(med.out)
}
}
-测试
param_dat <- list(
predictor = c("mpg", "cyl"),
mediator = c("drat", "disp", "wt", "cyl"),
outcome = c("qsec", "gear", "carb", "hp"),
data = c("mtcars")
) %>% cross_df
out <- param_dat %>%
slice_head(n = 2)%>%
pmap(., causal_med_so)
Running nonparametric bootstrap
Running nonparametric bootstrap
-输出
> str(out)
List of 2
$ :List of 56
..$ d0 : num -0.0731
..$ d1 : num -0.0731
..$ d0.ci : Named num [1:2] -0.1545 0.0325
.. ..- attr(*, "names")= chr [1:2] "3.053716%" "97.96547%"
..$ d1.ci : Named num [1:2] -0.1545 0.0325
.. ..- attr(*, "names")= chr [1:2] "3.053716%" "97.96547%"
..$ d0.p : num 0.158
..$ d1.p : num 0.158
..$ d0.sims : num [1:1000, 1] -0.0181 -0.0445 -0.0792 -0.1008 -0.088 ...
..$ d1.sims : num [1:1000, 1] -0.0181 -0.0445 -0.0792 -0.1008 -0.088 ...
..$ z0 : num 0.197
..$ z1 : num 0.197
..$ z0.ci : Named num [1:2] 0.0461 0.3122
.. ..- attr(*, "names")= chr [1:2] "1.787667%" "96.56288%"
..$ z1.ci : Named num [1:2] 0.0461 0.3122
.. ..- attr(*, "names")= chr [1:2] "1.787667%" "96.56288%"
...
我创建了一个函数来进行某种类型的分析:
library(tidyverse)
library(mediation)
causal_med_so <- function(predictor, mediator, outcome, data, ...){
if(!missing(...)) {
data <- {{data}} %>%
dplyr::select({{predictor}}, {{mediator}}, {{outcome}}, ...) %>%
dplyr::filter(across(.cols = everything(), .fns = ~ !is.na(.)))
predictor <- enquo(predictor)
mediator <- enquo(mediator)
outcome <- enquo(outcome)
med.form <- formula(paste0(
quo_name(mediator), "~",
paste0(
quo_name(predictor), "+",
paste0(c(...), collapse = "+"),
collapse = "+"
)
))
med.fit <- eval(bquote(lm(.(med.form), data = data)))
out.form <- formula(paste0(quo_name(outcome), "~",
paste0(
quo_name(predictor), "+",
quo_name(mediator), "+",
paste0(c(...), collapse = "+"),
collapse = "+"
)))
out.fit <- eval(bquote(lm(.(out.form), data = data)))
med.out <- mediation::mediate(med.fit, out.fit,
treat = quo_name(predictor),
mediator = quo_name(mediator),
boot=T, boot.ci.type = "bca")
return(med.out)
} else {
data <- {{data}} %>%
dplyr::select({{predictor}}, {{mediator}}, {{outcome}}) %>%
dplyr::filter(across(.cols = everything(), .fns = ~ !is.na(.)))
predictor <- enquo(predictor)
mediator <- enquo(mediator)
outcome <- enquo(outcome)
med.form <- formula(paste0(quo_name(mediator), "~", quo_name(predictor)))
med.fit <- eval(bquote(lm(.(med.form), data = data)))
out.form <- formula(paste0(quo_name(outcome), "~",
quo_name(predictor), "+", quo_name(mediator)))
out.fit <- eval(bquote(lm(.(out.form), data = data)))
med.out <- mediation::mediate(med.fit, out.fit,
treat = quo_name(predictor),
mediator = quo_name(mediator),
boot=T, boot.ci.type = "bca")
return(med.out)
}
}
函数似乎按预期运行:
causal_med_so(mpg, cyl, qsec, mtcars)
我现在想在 apply/map/pmap 调用中使用此函数,以所有可能的组合一次调用 运行 许多模型:
param_list <- list(
predictor = c("mpg", "cyl"),
mediator = c("drat", "disp", "wt", "cyl"),
outcome = c("qsec", "gear", "carb", "hp"),
data = c("mtcars")
) %>%
cross()
我正在尝试做这样的事情:
lmap(param_list, causal_med_so)
lapply(param_list, causal_med_so)
但是我遇到了一些错误消息,提示列表元素被视为字符。我尝试了 noquote()
、syms()
、!!!syms()
的几种组合,但似乎无法找到解决方案。
因为这些是字符串,所以最好转换为 sym
bol 并计算 (!!
)(为了测试,只使用 'param_dat' 的前两行(更改为 cross
到 cross_df
从而 return a tibble
)
causal_med_so <- function(predictor, mediator, outcome, data, ...){
predictor <- rlang::ensym(predictor)
mediator <- rlang::ensym(mediator)
outcome <- rlang::ensym(outcome)
if(!missing(...)) {
data <- get(data, envir = .GlobalEnv) %>%
dplyr::select(!!predictor, !!mediator, !!outcome, ...) %>%
dplyr::filter(across(.cols = everything(), .fns = ~ !is.na(.)))
predictor <- enquo(predictor)
mediator <- enquo(mediator)
outcome <- enquo(outcome)
med.form <- formula(paste0(
quo_name(mediator), "~",
paste0(
quo_name(predictor), "+",
paste0(c(...), collapse = "+"),
collapse = "+"
)
))
med.fit <- eval(bquote(lm(.(med.form), data = data)))
out.form <- formula(paste0(quo_name(outcome), "~",
paste0(
quo_name(predictor), "+",
quo_name(mediator), "+",
paste0(c(...), collapse = "+"),
collapse = "+"
)))
out.fit <- eval(bquote(lm(.(out.form), data = data)))
med.out <- mediation::mediate(med.fit, out.fit,
treat = quo_name(predictor),
mediator = quo_name(mediator),
boot=T, boot.ci.type = "bca")
return(med.out)
} else {
data <- get(data, envir = .GlobalEnv) %>%
dplyr::select(!!predictor, !!mediator, !!outcome) %>%
dplyr::filter(across(.cols = everything(), .fns = ~ !is.na(.)))
med.form <- formula(paste0(quo_name(mediator), "~", quo_name(predictor)))
med.fit <- eval(bquote(lm(.(med.form), data = data)))
out.form <- formula(paste0(quo_name(outcome), "~",
quo_name(predictor), "+", quo_name(mediator)))
out.fit <- eval(bquote(lm(.(out.form), data = data)))
med.out <- mediation::mediate(med.fit, out.fit,
treat = quo_name(predictor),
mediator = quo_name(mediator),
boot=T, boot.ci.type = "bca")
return(med.out)
}
}
-测试
param_dat <- list(
predictor = c("mpg", "cyl"),
mediator = c("drat", "disp", "wt", "cyl"),
outcome = c("qsec", "gear", "carb", "hp"),
data = c("mtcars")
) %>% cross_df
out <- param_dat %>%
slice_head(n = 2)%>%
pmap(., causal_med_so)
Running nonparametric bootstrap
Running nonparametric bootstrap
-输出
> str(out)
List of 2
$ :List of 56
..$ d0 : num -0.0731
..$ d1 : num -0.0731
..$ d0.ci : Named num [1:2] -0.1545 0.0325
.. ..- attr(*, "names")= chr [1:2] "3.053716%" "97.96547%"
..$ d1.ci : Named num [1:2] -0.1545 0.0325
.. ..- attr(*, "names")= chr [1:2] "3.053716%" "97.96547%"
..$ d0.p : num 0.158
..$ d1.p : num 0.158
..$ d0.sims : num [1:1000, 1] -0.0181 -0.0445 -0.0792 -0.1008 -0.088 ...
..$ d1.sims : num [1:1000, 1] -0.0181 -0.0445 -0.0792 -0.1008 -0.088 ...
..$ z0 : num 0.197
..$ z1 : num 0.197
..$ z0.ci : Named num [1:2] 0.0461 0.3122
.. ..- attr(*, "names")= chr [1:2] "1.787667%" "96.56288%"
..$ z1.ci : Named num [1:2] 0.0461 0.3122
.. ..- attr(*, "names")= chr [1:2] "1.787667%" "96.56288%"
...