In the following code I try to create a list tibble column at the right end of mtcars
, in which: each member of the list is a tibble with rows of mtcars tibble where vs >= 1
and !is.na(gear)
.
In purrr::map2()
, I am using !!dplyr::sym()
to convert the input strings to tibble variables for use in dplyr::filter()
and tidyr::drop_na()
, but this results in an error of
“object ‘.x’ not found”.
Why is this happening?
I know that if I use dplyr::filter_at(.x, ~ {.x >= 1})
and tidyr::drop_na(all_of(.y))
, I can avoid this error. But is there anything wrong if I want to convert the arguments .x
and .y
from strings to tibble variables and use them in filter()
and drop_na()
? (I remember they accept unquoted tibble variables)
Thanks for your help and suggestions.
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
Created on 2020-06-10 by the reprex package (v0.3.0)
My session info:
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
2
Answers
It is not possible to use
!! rlang::sym
in amap
call nested insidemutate
(it only works within the top level ofmutate
. You can either write a custom funcion, where you use!! rlang::sym()
and call this withinmap2
. Or you could useeval
instead of!!
.Below is an option using a custom function. However, I am not sure how your desired output looks like. Also, using a string of length 1 in a
map
call, doesn’t make much sense, since we could produce the same outcome withoutmap
.Created on 2020-06-10 by the reprex package (v0.3.0)
Note that you can produce the same outcome by just calling the custom function inside
mutate
wrapped inlist
(you might need dplyr 1.0.0 for this functinonality):This would be an alternative using
eval
andmap2
:Created on 2020-06-10 by the reprex package (v0.3.0)
Add on
Since the OP shows a very minimal example, here is a more realistic approach where the
tibble
contains a character column with variable names. In this casemap
is no longer needed underdplyr >= 1.0.0
, since we can userowwise
andmutate
.Created on 2020-06-10 by the reprex package (v0.3.0)
dplyr::sym
creates a symbol from a string; you’d have to writedplyr::sym(".x")
.