r语言 - 在创建列表 tibble 列时在 "mutation" 中使用 dplyr::sym() 会导致错误 is_symbol(x):找不到对象 '.x'



在下面的代码中,我尝试在mtcars的右端创建一个列表 tibble 列,其中:列表的每个成员都是一个 tibble,其中有一排排 mtcars tibble,其中vs >= 1!is.na(gear)

purrr::map2()中,我使用!!dplyr::sym()将输入字符串转换为 tibble 变量以用于dplyr::filter()tidyr::drop_na(),但这会导致错误

"找不到对象'.x'"。

为什么会这样?

我知道如果我使用dplyr::filter_at(.x, ~ {.x >= 1})tidyr::drop_na(all_of(.y)),我可以避免此错误。但是,如果我想将参数.x.y从字符串转换为 tibble 变量并在filter()drop_na()中使用它们,有什么问题吗?(我记得他们接受未引用的 tibble 变量(

感谢您的帮助和建议。

library(tidyverse)
mtcars %>%
tibble::as_tibble() %>%
dplyr::mutate(vs2 = purrr::map2("vs", "gear", ~ {
mtcars %>%
tibble::as_tibble() %>%
dplyr::filter(!!dplyr::sym(.x) >= 1) %>%
tidyr::drop_na(!!dplyr::sym(.y))
}))
#> Error in is_symbol(x): object '.x' not found

创建于 2020-06-10 由 reprex 软件包 (v0.3.0(

我的会话信息:

sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-redhat-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)
Matrix products: default
BLAS/LAPACK: /usr/lib64/R/lib/libRblas.so
locale:
[1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8       
[4] LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
[7] LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C              
[10] LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     
other attached packages:
[1] forcats_0.5.0   stringr_1.4.0   dplyr_0.8.3     purrr_0.3.3     readr_1.3.1    
[6] tidyr_1.0.2     tibble_2.1.3    ggplot2_3.2.1   tidyverse_1.3.0 shiny_1.4.0.2  
loaded via a namespace (and not attached):
[1] Rcpp_1.0.3       lubridate_1.7.4  lattice_0.20-38  ps_1.3.2         assertthat_0.2.1
[6] digest_0.6.23    mime_0.8         R6_2.4.1         cellranger_1.1.0 backports_1.1.5 
[11] reprex_0.3.0     evaluate_0.14    httr_1.4.1       pillar_1.4.3     rlang_0.4.6     
[16] lazyeval_0.2.2   readxl_1.3.1     rstudioapi_0.10  miniUI_0.1.1.1   whisker_0.4     
[21] callr_3.4.2      rmarkdown_2.1    munsell_0.5.0    broom_0.5.5      compiler_3.6.0  
[26] httpuv_1.5.3.1   modelr_0.1.6     xfun_0.11        pkgconfig_2.0.3  clipr_0.7.0     
[31] htmltools_0.4.0  tidyselect_1.0.0 fansi_0.4.0      crayon_1.3.4     dbplyr_1.4.2    
[36] withr_2.1.2      later_1.0.0      grid_3.6.0       nlme_3.1-139     jsonlite_1.6    
[41] xtable_1.8-4     gtable_0.3.0     lifecycle_0.1.0  DBI_1.1.0        magrittr_1.5    
[46] scales_1.1.0     cli_2.0.0        stringi_1.4.3    fs_1.3.1         promises_1.1.0  
[51] xml2_1.2.2       vctrs_0.2.4      generics_0.0.2   tools_3.6.0      glue_1.3.1      
[56] hms_0.5.2        processx_3.4.2   fastmap_1.0.1    colorspace_1.4-1 rvest_0.3.5     
[61] knitr_1.26       haven_2.2.0     

在嵌套在mutate中的map调用中无法使用!! rlang::sym(它仅适用于mutate的顶级。您可以编写自定义功能,在其中使用!! rlang::sym()并在map2中调用此功能。或者您可以使用eval而不是!!

下面是使用自定义函数的选项。但是,我不确定您想要的输出是什么样子的。此外,在map调用中使用长度为 1 的字符串没有多大意义,因为我们可以在没有map的情况下产生相同的结果。

library(tidyverse)
filter_df <- function(x, y) {
mtcars %>% 
tibble::as_tibble() %>%
dplyr::filter(!! rlang::sym(x) >= 1,
!is.na(!! rlang::sym(y)))
}
mtcars %>%
tibble::as_tibble() %>%
mutate(vs2 = map2("vs", "gear", filter_df))
#> # A tibble: 32 x 12
#>      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb vs2        
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <list>     
#>  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4 <tibble [1~
#>  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4 <tibble [1~
#>  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1 <tibble [1~
#>  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1 <tibble [1~
#>  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2 <tibble [1~
#>  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1 <tibble [1~
#>  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4 <tibble [1~
#>  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2 <tibble [1~
#>  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2 <tibble [1~
#> 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4 <tibble [1~
#> # ... with 22 more rows

由 reprex 包 (v0.3.0( 于 2020-06-10 创建请注意

,您只需调用包装在list中的自定义函数mutate即可产生相同的结果(您可能需要 dplyr 1.0.0 来实现此功能(:

mtcars %>%
tibble::as_tibble() %>%
mutate(vs2 = list(filter_df("vs", "gear")))



这将是使用evalmap2的替代方法:

library(tidyverse)
mtcars %>%
tibble::as_tibble() %>%
mutate(vs2 = map2("vs", "gear",
~ mtcars %>% 
tibble::as_tibble() %>%
dplyr::filter(eval(rlang::sym(.x)) >= 1,
!is.na(eval(rlang::sym(.y))))
)
)
#> # A tibble: 32 x 12
#>      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb vs2        
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <list>     
#>  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4 <tibble [1~
#>  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4 <tibble [1~
#>  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1 <tibble [1~
#>  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1 <tibble [1~
#>  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2 <tibble [1~
#>  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1 <tibble [1~
#>  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4 <tibble [1~
#>  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2 <tibble [1~
#>  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2 <tibble [1~
#> 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4 <tibble [1~
#> # ... with 22 more rows

创建于 2020-06-10 由 reprex 软件包 (v0.3.0(


附加

由于 OP 显示了一个非常小的示例,因此这里有一种更现实的方法,其中tibble包含一个带有变量名称的字符列。在这种情况下,map不再需要dplyr >= 1.0.0,因为我们可以使用rowwisemutate.

library(tidyverse)
filter_df <- function(df, x) {
df %>% 
tibble::as_tibble() %>%
dplyr::filter(!! rlang::sym(x) >= mean(!! rlang::sym(x)))
}
tibble(data = list(tibble(mtcars)),
var_names = names(mtcars)) %>% 
rowwise() %>% 
mutate(new_data = list(filter_df(data, var_names)))
#> # A tibble: 11 x 3
#> # Rowwise: 
#>    data               var_names new_data          
#>    <list>             <chr>     <list>            
#>  1 <tibble [32 × 11]> mpg       <tibble [14 × 11]>
#>  2 <tibble [32 × 11]> cyl       <tibble [14 × 11]>
#>  3 <tibble [32 × 11]> disp      <tibble [15 × 11]>
#>  4 <tibble [32 × 11]> hp        <tibble [15 × 11]>
#>  5 <tibble [32 × 11]> drat      <tibble [18 × 11]>
#>  6 <tibble [32 × 11]> wt        <tibble [16 × 11]>
#>  7 <tibble [32 × 11]> qsec      <tibble [15 × 11]>
#>  8 <tibble [32 × 11]> vs        <tibble [14 × 11]>
#>  9 <tibble [32 × 11]> am        <tibble [13 × 11]>
#> 10 <tibble [32 × 11]> gear      <tibble [17 × 11]>
#> 11 <tibble [32 × 11]> carb      <tibble [15 × 11]>

创建于 2020-06-10 由 reprex 软件包 (v0.3.0(

dplyr::sym

字符串创建一个符号;你必须写dplyr::sym(".x")

最新更新