在 tidyeval 中包装模型时如何改变公式参数的一部分?
How can I vary part of a formula argument when wrapping models in tidyeval?
据我所知,当您想创建包装模型的函数时,有两种处理公式参数的方法。您可以将公式的字符串版本粘贴在一起:
library(tidyverse)
run_model1 <- function(df, dep_str, ...){
groupers <- enquos(...)
formula <- dep_str %>% str_c("~ cty") %>% as.formula()
df %>%
group_by(!!!groupers) %>%
do(model = lm(formula, data = .))
}
或者您可以引用整个公式:
run_model2 <- function(df, formula, ...){
groupers <- enquos(...)
formula <- enexpr(formula)
df %>%
group_by(!!!groupers) %>%
do(model = lm(!!formula, data = .))
}
这两者实际上都允许我在改变公式中的变量时获得分组模型。
run_model1(mpg, "hwy", cyl)
#> Source: local data frame [4 x 2]
#> Groups: <by row>
#>
#> # A tibble: 4 x 2
#> cyl model
#> * <int> <list>
#> 1 4 <S3: lm>
#> 2 5 <S3: lm>
#> 3 6 <S3: lm>
#> 4 8 <S3: lm>
run_model2(mpg, hwy ~ cty, cyl)
#> Source: local data frame [4 x 2]
#> Groups: <by row>
#>
#> # A tibble: 4 x 2
#> cyl model
#> * <int> <list>
#> 1 4 <S3: lm>
#> 2 5 <S3: lm>
#> 3 6 <S3: lm>
#> 4 8 <S3: lm>
但是,第一个需要引用和未引用参数的笨拙混合,尤其是如果我想访问符号版本供以后使用,则效果不佳。第二个迫使我每次都提供整个公式,而我宁愿只提供一部分。
基本上,我怎样才能得到一个接受这样参数的函数?
run_model3(mpg, hwy, cyl)
ensym()
应该让您捕获提供给函数的符号。
ensym()
and ensyms()
are variants of enexpr()
and enexprs()
that check
the captured expression is either a string (which they convert to
symbol) or a symbol. If anything else is supplied they throw an error.
run_model3 <- function (df, dep_str, ...) {
dep_str <- ensym(dep_str)
groupers <- enquos(...)
formula <- dep_str %>% str_c("~ cty") %>% as.formula()
df %>%
group_by(!!!groupers) %>%
do(model = lm(formula, data = .))
}
> run_model3(mpg, hwy, cyl)
Source: local data frame [4 x 2]
Groups: <by row>
# A tibble: 4 x 2
cyl model
* <int> <list>
1 4 <S3: lm>
2 5 <S3: lm>
3 6 <S3: lm>
4 8 <S3: lm>
并且在我们甚至可以使用 run_model1
的当前方法之前根据报价:
> run_model3(mpg, "hwy", cyl)
Source: local data frame [4 x 2]
Groups: <by row>
# A tibble: 4 x 2
cyl model
* <int> <list>
1 4 <S3: lm>
2 5 <S3: lm>
3 6 <S3: lm>
4 8 <S3: lm>
据我所知,当您想创建包装模型的函数时,有两种处理公式参数的方法。您可以将公式的字符串版本粘贴在一起:
library(tidyverse)
run_model1 <- function(df, dep_str, ...){
groupers <- enquos(...)
formula <- dep_str %>% str_c("~ cty") %>% as.formula()
df %>%
group_by(!!!groupers) %>%
do(model = lm(formula, data = .))
}
或者您可以引用整个公式:
run_model2 <- function(df, formula, ...){
groupers <- enquos(...)
formula <- enexpr(formula)
df %>%
group_by(!!!groupers) %>%
do(model = lm(!!formula, data = .))
}
这两者实际上都允许我在改变公式中的变量时获得分组模型。
run_model1(mpg, "hwy", cyl)
#> Source: local data frame [4 x 2]
#> Groups: <by row>
#>
#> # A tibble: 4 x 2
#> cyl model
#> * <int> <list>
#> 1 4 <S3: lm>
#> 2 5 <S3: lm>
#> 3 6 <S3: lm>
#> 4 8 <S3: lm>
run_model2(mpg, hwy ~ cty, cyl)
#> Source: local data frame [4 x 2]
#> Groups: <by row>
#>
#> # A tibble: 4 x 2
#> cyl model
#> * <int> <list>
#> 1 4 <S3: lm>
#> 2 5 <S3: lm>
#> 3 6 <S3: lm>
#> 4 8 <S3: lm>
但是,第一个需要引用和未引用参数的笨拙混合,尤其是如果我想访问符号版本供以后使用,则效果不佳。第二个迫使我每次都提供整个公式,而我宁愿只提供一部分。
基本上,我怎样才能得到一个接受这样参数的函数?
run_model3(mpg, hwy, cyl)
ensym()
应该让您捕获提供给函数的符号。
ensym()
andensyms()
are variants ofenexpr()
andenexprs()
that check the captured expression is either a string (which they convert to symbol) or a symbol. If anything else is supplied they throw an error.
run_model3 <- function (df, dep_str, ...) {
dep_str <- ensym(dep_str)
groupers <- enquos(...)
formula <- dep_str %>% str_c("~ cty") %>% as.formula()
df %>%
group_by(!!!groupers) %>%
do(model = lm(formula, data = .))
}
> run_model3(mpg, hwy, cyl)
Source: local data frame [4 x 2]
Groups: <by row>
# A tibble: 4 x 2
cyl model
* <int> <list>
1 4 <S3: lm>
2 5 <S3: lm>
3 6 <S3: lm>
4 8 <S3: lm>
并且在我们甚至可以使用 run_model1
的当前方法之前根据报价:
> run_model3(mpg, "hwy", cyl)
Source: local data frame [4 x 2]
Groups: <by row>
# A tibble: 4 x 2
cyl model
* <int> <list>
1 4 <S3: lm>
2 5 <S3: lm>
3 6 <S3: lm>
4 8 <S3: lm>