r - 在创建列表 tibble 列时在 "mutation"中使用 dplyr::sym() 会导

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

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

"object '.x' not found".

为什么会这样?

我知道如果我使用 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

由 reprex package 创建于 2020-06-10 (v0.3.0)

我的 session 信息:

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 package 创建于 2020-06-10 (v0.3.0)

请注意,您可以通过调用包含在 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

由 reprex package 创建于 2020-06-10 (v0.3.0)


添加

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

由 reprex package 创建于 2020-06-10 (v0.3.0)

关于r - 在创建列表 tibble 列时在 "mutation"中使用 dplyr::sym() 会导致错误 is_symbol(x): object '.x' not found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62299602/

相关文章:

python - psutil.AccessDenied : psutil. AccessDenie

python - tqdm.notebook 在 jupyter notebook 中显示带有 "H

python - 查找列表中的值是否大于其下方的项目

graphql-java - 读取通过 G​​raphQL Java 中的变量传递的字段参数

ethereum - 返回错误 : The method web3_clientVersion do

matlab - 使用鼠标右键删除选择表中的行 - Matlab 2020a

c# - 如何评估包含局部变量名称的字符串作为 C# 中的代码

google-cloud-functions - GCP Console : console. lo

c# - Json 列 SQL

docker - 无法加载动态库 'libcuda.so.1'; dlerror : libcuda