Квазиквотация и ifelse: Unquoting не разрешается, как ожидалось - PullRequest
0 голосов
/ 27 февраля 2019

Я ожидал, что смогу использовать механизмы квазиквотации из пакета rlang, такие как !! и quo_name(), для отмены цитирования имени программы в mutate() и в функции ifelse().Однако, это не сработало, как я ожидал, что я покажу ниже.Вместо того, чтобы разрешать значение имени в области данных в кадре ifelse() внутри вызова mutate(), оно разрешало только символьное значение параметра.Я смог использовать базовую функцию get(), чтобы делать то, что я хочу.Тем не менее, я, должно быть, что-то путаю и ищу, как это сделать в мире rlang / quasiquotation.Объяснение и помощь приветствуются.

suppressPackageStartupMessages(library(tidyverse))

df <- tibble(x=c(1, NA_integer_, 3), y=101:103)
print(df)
#> # A tibble: 3 x 2
#>       x     y
#>   <dbl> <int>
#> 1     1   101
#> 2    NA   102
#> 3     3   103

# Expected behavior
df %>%
    mutate(z = ifelse(is.na(x), y, x))
#> # A tibble: 3 x 3
#>       x     y     z
#>   <dbl> <int> <dbl>
#> 1     1   101     1
#> 2    NA   102   102
#> 3     3   103     3

# Similar question seemed to be posted here:
# From: https://community.rstudio.com/t/trouble-with-creating-column-names-from-a-passed-argument-in-function/7819/3
# I expect same output as above, but instead, the column `x` gets filled with the name of the column, not appropriate value.
v_colname <- "x"
df %>%
    mutate(z := ifelse(is.na(!!v_colname), y, !!v_colname)) %>%
    print()
#> # A tibble: 3 x 3
#>       x     y z    
#>   <dbl> <int> <chr>
#> 1     1   101 x    
#> 2    NA   102 x    
#> 3     3   103 x

# Tried variant with `quo_name()`, same unexpected result:
df %>%
    mutate(z := ifelse(is.na(!!quo_name(v_colname)), y, !!quo_name(v_colname)))
#> # A tibble: 3 x 3
#>       x     y z    
#>   <dbl> <int> <chr>
#> 1     1   101 x    
#> 2    NA   102 x    
#> 3     3   103 x

# This works, but I assume I am missing something with quasiquotation semantics:
df %>%
    mutate(z := ifelse(is.na(get(v_colname)), y, get(v_colname)))
#> # A tibble: 3 x 3
#>       x     y     z
#>   <dbl> <int> <dbl>
#> 1     1   101     1
#> 2    NA   102   102
#> 3     3   103     3

# Session info
sessionInfo()
#> R version 3.5.2 (2018-12-20)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 16299)
#> 
#> Matrix products: default
#> 
#> locale:
#> [1] LC_COLLATE=English_United States.1252 
#> [2] LC_CTYPE=English_United States.1252   
#> [3] LC_MONETARY=English_United States.1252
#> [4] LC_NUMERIC=C                          
#> [5] LC_TIME=English_United States.1252    
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#>  [1] bindrcpp_0.2.2  forcats_0.3.0   stringr_1.3.1   dplyr_0.7.8    
#>  [5] purrr_0.2.5     readr_1.3.1     tidyr_0.8.2     tibble_2.0.1   
#>  [9] ggplot2_3.1.0   tidyverse_1.2.1
#> 
#> loaded via a namespace (and not attached):
#>  [1] Rcpp_1.0.0       cellranger_1.1.0 plyr_1.8.4       pillar_1.3.1    
#>  [5] compiler_3.5.2   highr_0.7        bindr_0.1.1      tools_3.5.2     
#>  [9] digest_0.6.18    lubridate_1.7.4  jsonlite_1.6     evaluate_0.12   
#> [13] nlme_3.1-137     gtable_0.2.0     lattice_0.20-38  pkgconfig_2.0.2 
#> [17] rlang_0.3.1      cli_1.0.1        yaml_2.2.0       haven_2.0.0     
#> [21] xfun_0.4         withr_2.1.2      xml2_1.2.0       httr_1.4.0      
#> [25] knitr_1.21       hms_0.4.2        generics_0.0.2   grid_3.5.2      
#> [29] tidyselect_0.2.5 glue_1.3.0       R6_2.3.0         fansi_0.4.0     
#> [33] readxl_1.2.0     rmarkdown_1.11   modelr_0.1.2     magrittr_1.5    
#> [37] backports_1.1.3  scales_1.0.0     htmltools_0.3.6  rvest_0.3.2     
#> [41] assertthat_0.2.0 colorspace_1.4-0 utf8_1.1.4       stringi_1.2.4   
#> [45] lazyeval_0.2.1   munsell_0.5.0    broom_0.5.1      crayon_1.3.4

Создано в 2019-02-27 пакетом Представить (v0.2.1)

1 Ответ

0 голосов
/ 27 февраля 2019

Мы можем преобразовать в символ (sym) и затем оценить (!!)

library(dplyr)
df %>%
  mutate(z := ifelse(is.na(!!rlang::sym(v_colname)), y, !! rlang::sym(v_colname)))
# A tibble: 3 x 3
#      x     y     z
#  <dbl> <int> <dbl>
#1     1   101     1
#2    NA   102   102
#3     3   103     3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...