我期望我可以使用rlang
包中的准引用机制,例如!!
和quo_name()
来在mutate()
和ifelse()
中用程序将名称取消引用功能。但是,它没有按我预期的那样工作,如下所示。它没有解析ifelse()
调用内mutate()
内数据框范围内的名称值,而是仅解析参数的字符值。我能够使用基本功能get()
来完成我想要的事情。但是,我一定会感到困惑,并且正在寻找如何在Rlang /准引用世界中做到这一点。说明和帮助表示赞赏。
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
由reprex package(v0.2.1)于2019-02-27创建
答案 0 :(得分:1)
我们可以转换为符号(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