как использовать tidydots в case_when?

#r #rlang #tidyeval

#r #rlang #tidyeval

Вопрос:

В документации для dplyr::case_when указано, что «Эти точки поддерживают функции tidy dots. В частности, если ваши шаблоны хранятся в списке, вы можете объединить их с !!!.» Но, похоже, я не могу понять, как это сделать. И существующие вопросы по этой проблеме в stackoverflow кажутся устаревшими — возможно, они были до rlang 0.3.0.

Вот что я пробовал:

 my_cases <- list(
  Species == "setosa" ~ "S",
  TRUE ~ "other"
)

tiris <- tibble::as_tibble(iris)
tiris
#> # A tibble: 150 x 5
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>           <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#>  1          5.1         3.5          1.4         0.2 setosa 
#>  2          4.9         3            1.4         0.2 setosa 
#>  3          4.7         3.2          1.3         0.2 setosa 
#>  4          4.6         3.1          1.5         0.2 setosa 
#>  5          5           3.6          1.4         0.2 setosa 
#>  6          5.4         3.9          1.7         0.4 setosa 
#>  7          4.6         3.4          1.4         0.3 setosa 
#>  8          5           3.4          1.5         0.2 setosa 
#>  9          4.4         2.9          1.4         0.2 setosa 
#> 10          4.9         3.1          1.5         0.1 setosa 
#> # … with 140 more rows

dplyr::mutate(tiris,
  new_label = dplyr::case_when(!!!my_cases)
)
#> Error in eval_tidy(pair$lhs, env = default_env): object 'Species' not found





devtools::session_info()
#> ─ Session info ──────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 3.5.3 (2019-03-11)
#>  os       macOS Mojave 10.14.3        
#>  system   x86_64, darwin15.6.0        
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  ctype    en_US.UTF-8                 
#>  tz       America/New_York            
#>  date     2019-03-31                  
#> 
#> ─ Packages ──────────────────────────────────────────────────────────────
#>  package     * version date       lib source        
#>  assertthat    0.2.1   2019-03-21 [1] CRAN (R 3.5.3)
#>  backports     1.1.3   2018-12-14 [1] CRAN (R 3.5.0)
#>  callr         3.2.0   2019-03-15 [1] CRAN (R 3.5.1)
#>  cli           1.1.0   2019-03-19 [1] CRAN (R 3.5.1)
#>  crayon        1.3.4   2017-09-16 [1] CRAN (R 3.5.0)
#>  desc          1.2.0   2018-05-01 [1] CRAN (R 3.5.0)
#>  devtools      2.0.1   2018-10-26 [1] CRAN (R 3.5.3)
#>  digest        0.6.18  2018-10-10 [1] CRAN (R 3.5.0)
#>  dplyr         0.8.0.1 2019-02-15 [1] CRAN (R 3.5.2)
#>  evaluate      0.13    2019-02-12 [1] CRAN (R 3.5.2)
#>  fansi         0.4.0   2018-10-05 [1] CRAN (R 3.5.0)
#>  fs            1.2.7   2019-03-19 [1] CRAN (R 3.5.3)
#>  glue          1.3.1   2019-03-12 [1] CRAN (R 3.5.1)
#>  highr         0.8     2019-03-20 [1] CRAN (R 3.5.3)
#>  htmltools     0.3.6   2017-04-28 [1] CRAN (R 3.5.0)
#>  knitr         1.22    2019-03-08 [1] CRAN (R 3.5.2)
#>  magrittr      1.5     2014-11-22 [1] CRAN (R 3.5.0)
#>  memoise       1.1.0   2017-04-21 [1] CRAN (R 3.5.0)
#>  pillar        1.3.1   2018-12-15 [1] CRAN (R 3.5.0)
#>  pkgbuild      1.0.3   2019-03-20 [1] CRAN (R 3.5.3)
#>  pkgconfig     2.0.2   2018-08-16 [1] CRAN (R 3.5.0)
#>  pkgload       1.0.2   2018-10-29 [1] CRAN (R 3.5.0)
#>  prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.5.0)
#>  processx      3.3.0   2019-03-10 [1] CRAN (R 3.5.2)
#>  ps            1.3.0   2018-12-21 [1] CRAN (R 3.5.0)
#>  purrr         0.3.2   2019-03-15 [1] CRAN (R 3.5.1)
#>  R6            2.4.0   2019-02-14 [1] CRAN (R 3.5.2)
#>  Rcpp          1.0.1   2019-03-17 [1] CRAN (R 3.5.1)
#>  remotes       2.0.2   2018-10-30 [1] CRAN (R 3.5.0)
#>  rlang         0.3.3   2019-03-29 [1] CRAN (R 3.5.3)
#>  rmarkdown     1.12    2019-03-14 [1] CRAN (R 3.5.1)
#>  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.5.0)
#>  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.5.0)
#>  stringi       1.4.3   2019-03-12 [1] CRAN (R 3.5.1)
#>  stringr       1.4.0   2019-02-10 [1] CRAN (R 3.5.2)
#>  testthat      2.0.1   2018-10-13 [1] CRAN (R 3.5.0)
#>  tibble        2.1.1   2019-03-16 [1] CRAN (R 3.5.1)
#>  tidyselect    0.2.5   2018-10-11 [1] CRAN (R 3.5.0)
#>  usethis       1.4.0   2018-08-14 [1] CRAN (R 3.5.0)
#>  utf8          1.1.4   2018-05-24 [1] CRAN (R 3.5.0)
#>  withr         2.1.2   2018-03-15 [1] CRAN (R 3.5.0)
#>  xfun          0.5     2019-02-20 [1] CRAN (R 3.5.2)
#>  yaml          2.2.0   2018-07-25 [1] CRAN (R 3.5.0)
#> 
#> [1] /Library/Frameworks/R.framework/Versions/3.5/Resources/library
  

Ответ №1:

Одним из вариантов было бы создать запрос ( quos ), а затем использовать !!!

 my_cases <-   quos(Species == "setosa" ~ "S", 
                    TRUE ~ "other")

out <-  tiris %>% 
            mutate(new_lable = case_when(!!! my_cases))
head(out, 3)
# A tibble: 3 x 6
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species new_lable
#         <dbl>       <dbl>        <dbl>       <dbl> <fct>   <chr>    
#1          5.1         3.5          1.4         0.2 setosa  S        
#2          4.9         3            1.4         0.2 setosa  S        
#3          4.7         3.2          1.3         0.2 setosa  S        

tail(out, 3)
# A tibble: 3 x 6
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species   new_lable
#         <dbl>       <dbl>        <dbl>       <dbl> <fct>     <chr>    
#1          6.5         3            5.2         2   virginica other    
#2          6.2         3.4          5.4         2.3 virginica other    
#3          5.9         3            5.1         1.8 virginica other    
  

Комментарии:

1. В идеале синтаксис, который вы впервые попробовали, должен работать, но его сложно реализовать по неясным техническим причинам. Надеюсь, мы решим это в будущем.