dplyr functions and ensym

Working on programmating plotting with a plot function built with {{}}, and able to use maps2 with 2 vectors of inputs.
Then I try to use crossing to get all combinations of the input variables, which seems to produce a table of 2 character vectors, and use the same approach with ensyms, but it does not work.
Not sure
a) what I am doing wrong with all combinations? how to fix?
b) just as important, what subtlety am I not understanding here?

library(tidyverse)
library(palmerpenguins)
library(ggsignif)
library(glue)

# adaptive function will adjust p value bar height , title, and x axis label
plot_cats <- function(data, catvar, contvar){
  mv <- transmute(data,
      max := max({{contvar}},na.rm=TRUE)) |> 
    pull(max)
  
  data |> 
    ggplot() +
    aes(x = {{contvar}}, y = factor({{catvar}}), 
        fill=factor({{catvar}})) +
    geom_boxplot() +
    geom_jitter(width = 0.6) +
    geom_signif(comparisons = list(c(1,2))) +
    geom_signif(comparisons = list(c(1,3)), 
                y_position = 1.1 * mv) +
    geom_signif(comparisons = list(c(2,3)), 
                y_position = 1.2 * mv) +
    theme_bw() +
    theme(legend.position = "none",
          panel.grid.major.x  = element_blank()) +
    labs(y = "",
         x = glue("Measurement of {ensym(contvar)}"),
         title = glue("Comparison of {ensym(contvar)} \nAcross {ensym(catvar)} categories" ))
}

plot_cats(penguins, catvar = island, contvar = bill_length_mm)
#> Warning: Removed 2 rows containing non-finite values (`stat_boxplot()`).
#> Warning: Removed 2 rows containing non-finite values (`stat_signif()`).
#> Removed 2 rows containing non-finite values (`stat_signif()`).
#> Removed 2 rows containing non-finite values (`stat_signif()`).
#> Warning: Removed 2 rows containing missing values (`geom_point()`).



# Now make vector lists of catvars and contvars
catvars <- c('island', 'species', 'sex')

contvars <- c('bill_length_mm', 'body_mass_g', 'flipper_length_mm')

# Now plot the 3 pairs - works find with syms
# though it seems like contvars should be .x
# and catvars should be .y - but this version works

map2(.x = syms(catvars),
     .y = syms(contvars),
     .f = plot_cats, 
    data = penguins)
#> [[1]]
#> Warning: Removed 2 rows containing non-finite values (`stat_boxplot()`).
#> Warning: Removed 2 rows containing non-finite values (`stat_signif()`).
#> Removed 2 rows containing non-finite values (`stat_signif()`).
#> Removed 2 rows containing non-finite values (`stat_signif()`).
#> Warning: Removed 2 rows containing missing values (`geom_point()`).

#> 
#> [[2]]
#> Warning: Removed 2 rows containing non-finite values (`stat_boxplot()`).
#> Warning: Removed 2 rows containing non-finite values (`stat_signif()`).
#> Removed 2 rows containing non-finite values (`stat_signif()`).
#> Removed 2 rows containing non-finite values (`stat_signif()`).
#> Warning: Removed 2 rows containing missing values (`geom_point()`).

#> 
#> [[3]]
#> Warning: Removed 2 rows containing non-finite values (`stat_boxplot()`).
#> Warning: Removed 2 rows containing non-finite values (`stat_signif()`).
#> Removed 2 rows containing non-finite values (`stat_signif()`).
#> Removed 2 rows containing non-finite values (`stat_signif()`).
#> Warning: Removed 2 rows containing missing values (`geom_point()`).


# note this does the 3 pairs of catvars with contvars.
# to do all (9) combinations, let's set that up
# with an anaysis_list dataframe of all combos

analysis_list <- crossing(catvars, contvars)

# now for all possible (9) combinations
# This does NOT work
map2(.x = syms(analysis_list$catvars), 
     .y = syms(analysis_list$contvars), 
     .f = plot, 
     data = penguins) 
#> Error in `map2()`:
#> ℹ In index: 1.
#> Caused by error in `as.double()`:
#> ! cannot coerce type 'symbol' to vector of type 'double'
#> Backtrace:
#>      ▆
#>   1. ├─purrr::map2(...)
#>   2. │ └─purrr:::map2_("list", .x, .y, .f, ..., .progress = .progress)
#>   3. │   ├─purrr:::with_indexed_errors(...)
#>   4. │   │ └─base::withCallingHandlers(...)
#>   5. │   ├─purrr:::call_with_cleanup(...)
#>   6. │   ├─base (local) .f(.x[[i]], .y[[i]], ...)
#>   7. │   └─graphics::plot.default(.x[[i]], .y[[i]], ...)
#>   8. │     └─grDevices::xy.coords(x, y, xlabel, ylabel, log)
#>   9. └─base::.handleSimpleError(...)
#>  10.   └─purrr (local) h(simpleError(msg, call))
#>  11.     └─cli::cli_abort(...)
#>  12.       └─rlang::abort(...)

Created on 2023-09-21 with reprex v2.0.2

Do you mean to use plainplots here, rather than plot_cats?

3 Likes

Well that was silly.
Thank you.
I need a rubber duck.

map2(.x = syms(analysis_list$catvars), 
     .y = syms(analysis_list$contvars), 
     .f = plot_cats, 
     data = penguins)
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.