首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用‘`rlang::exec`’与使用‘`rlang::en符号’的函数

使用‘`rlang::exec`’与使用‘`rlang::en符号’的函数
EN

Stack Overflow用户
提问于 2019-08-02 14:08:00
回答 1查看 189关注 0票数 5

为了简单起见,我正在尝试编写一个更复杂的自定义函数,因此我创建了一些玩具示例。

假设我想写一个函数-

  1. 自动确定要运行的适当函数:例如,t-test或anova.
  2. 同时接受"quoted"unquoted参数

因此,我编写了一个函数来运行t-test (按预期工作):

代码语言:javascript
复制
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 (按预期工作):

代码语言:javascript
复制
# 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

然后我编写了一个元函数来从上面选择适当的函数-

代码语言:javascript
复制
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

但这似乎行不通。对于我在这里做错了什么,以及如何让它发挥作用,有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-02 15:20:48

问题似乎源于将相当于什么的内容(例如,通过元函数中的x = rlang::ensym(am)通过rlang::exec()传递给您的单个函数)。

ensym()函数只接受字符串或符号,这样做会导致错误消息。有鉴于此,将xy参数转换为字符串应该会有所帮助。

因此,元函数可以是:

代码语言:javascript
复制
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 (dplyr::n_distinct(data %>% dplyr::pull({{ x }})) == 2L) {
          .f <- fun_t
     } else {
          .f <- fun_anova
     }

     # executing the appropriate function
     rlang::exec(
          .fn = .f,
          data = data,
          x = rlang::as_string(x),
          y = rlang::as_string(y)
     )
}

(我从nlevels转到了nlevels,因为amcyl不是因素,所以我没有得到与原始结果相比较的正确结果。)

现在,使用裸符号和字符串可以工作:

代码语言:javascript
复制
fun_meta(mtcars, am, wt)
    # A tibble: 1 x 10
  estimate estimate1 estimate2 statistic p.value parameter conf.low conf.high
     <dbl>     <dbl>     <dbl>     <dbl>   <dbl>     <dbl>    <dbl>     <dbl>
1     1.36      3.77      2.41      5.49 6.27e-6      29.2    0.853      1.86
# ... with 2 more variables: method <chr>, alternative <chr>
> fun_meta(mtcars, "am", "wt")

fun_meta(mtcars, "am", "wt")
# A tibble: 1 x 10
  estimate estimate1 estimate2 statistic p.value parameter conf.low conf.high
     <dbl>     <dbl>     <dbl>     <dbl>   <dbl>     <dbl>    <dbl>     <dbl>
1     1.36      3.77      2.41      5.49 6.27e-6      29.2    0.853      1.86
# ... with 2 more variables: method <chr>, alternative <chr>
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57328124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档