创建列表标题列时在“突变”中使用dplyr :: sym()会导致错误is_symbol(x):找不到对象'.x'

Xiurui Zhu

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

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

“找不到对象'.x'”。

为什么会这样呢?

我知道如果使用dplyr::filter_at(.x, ~ {.x >= 1})tidyr::drop_na(all_of(.y)),可以避免此错误。但是,有什么不对,如果我要转换参数.x,并.y从字符串到tibble变量和使用它们filter()drop_na()(我记得他们接受未引用的小节变量)

感谢您的帮助和建议。

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

我的会话信息:

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     
蒂姆·范范

无法!! rlang::symmap嵌套调用中使用mutate(仅在的顶级中起作用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,

请注意,您可以通过调用mutate包装在其中的自定义函数来产生相同的结果(此功能list可能需要dplyr 1.0.0):

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



这是使用eval的替代方法map2

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


添加在

由于OP仅显示了一个非常小的示例,因此这是一种更实际的方法,其中tibble包含一个带有变量名的字符列。在这种情况mapdplyr >= 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]>

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档