Я пытаюсь написать собственную функцию, которая немного сложнее, поэтому для простоты я создал игрушечные примеры.
Скажем, я хочу написать функцию, которая ...
- автоматически выбирает подходящую функцию для запуска: например, t-тест или anova.
- принимает как
"quoted"
, так иunquoted
аргументы
Поэтому я пишу функцию для запуска t-теста (работает, как ожидалось):
set.seed(123)
library(rlang)
library(tidyverse)
# t-test function
fun_t <- function(data, x, y) {
# make sure both quoted and unquoted arguments work
x <- rlang::ensym(x)
y <- rlang::ensym(y)
# t-test
broom::tidy(stats::t.test(
formula = rlang::new_formula({{ y }}, {{ x }}),
data = data
))
}
# works fine
fun_t(mtcars, am, wt)
#> # A tibble: 1 x 10
#> estimate estimate1 estimate2 statistic p.value parameter conf.low
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1.36 3.77 2.41 5.49 6.27e-6 29.2 0.853
#> # ... with 3 more variables: conf.high <dbl>, method <chr>,
#> # alternative <chr>
fun_t(mtcars, "am", "wt")
#> # A tibble: 1 x 10
#> estimate estimate1 estimate2 statistic p.value parameter conf.low
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1.36 3.77 2.41 5.49 6.27e-6 29.2 0.853
#> # ... with 3 more variables: conf.high <dbl>, method <chr>,
#> # alternative <chr>
Затем я пишу функцию для запуска ановы (работает как положено):
# anova function
fun_anova <- function(data, x, y) {
# make sure both quoted and unquoted arguments work
x <- rlang::ensym(x)
y <- rlang::ensym(y)
# t-test
broom::tidy(stats::aov(
formula = rlang::new_formula({{ y }}, {{ x }}),
data = data
))
}
# works fine
fun_anova(mtcars, cyl, wt)
#> # A tibble: 2 x 6
#> term df sumsq meansq statistic p.value
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 cyl 1 18.2 18.2 47.4 0.000000122
#> 2 Residuals 30 11.5 0.384 NA NA
fun_anova(mtcars, "cyl", "wt")
#> # A tibble: 2 x 6
#> term df sumsq meansq statistic p.value
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 cyl 1 18.2 18.2 47.4 0.000000122
#> 2 Residuals 30 11.5 0.384 NA NA
Затем я пишу мета-функцию, чтобы выбрать соответствующую функцию из приведенных выше -
fun_meta <- function(data, x, y) {
# make sure both quoted and unquoted arguments work
x <- rlang::ensym(x)
y <- rlang::ensym(y)
# which test to run?
if (nlevels(data %>% dplyr::pull({{ x }})) == 2L) {
.f <- fun_t
} else {
.f <- fun_anova
}
# executing the appropriate function
rlang::exec(
.fn = .f,
data = data,
x = x,
y = y
)
}
# using the meta-function
fun_meta(mtcars, am, wt)
#> Only strings can be converted to symbols
fun_meta(mtcars, "am", "wt")
#> Only strings can be converted to symbols
Но, похоже, это не работает. Есть идеи о том, что я здесь делаю неправильно и как заставить это работать?
rlang::ensym(variable)
прямо в вашу функцию t.test:fun_t(mtcars, rlang::ensym(am), wt)
. Возможно, проблема связана с использованиемrlang::ensym()
в мета-функции? У меня нет решения, но с этого можно начать. - person aosmith   schedule 02.08.2019as_string()
в вашей мета-функции, чтобы превратить аргументы в строки для передачи в выбранную функцию:rlang::exec(.fn = .f,data = data,x = as_string(x), y = as_string(y))
- person aosmith   schedule 02.08.2019