Using mutate() within map() or walk()

Hello,

I'm having trouble using a function that includes mutate with the map or walk functions. As shown below, the function works on a single column in a dataframe, but when I attempt to apply the function to multiple columns using map, I get the error shown below. Any help to successfully apply the function to multiple columns would be greatly appreciated.

suppressWarnings(suppressPackageStartupMessages({
  library(tidyverse)
  library(janitor)
}))

# tabulation function
quick_tab <- function(df, x) {
  obj <- df %>% 
    tabyl({{x}}) %>% 
    adorn_totals() %>% 
    adorn_pct_formatting() %>% 
    mutate({{x}} := as_factor({{x}})) %>% 
    as_tibble()
  
  obj
}

# works as intended with a single column
mtcars %>% 
  quick_tab(cyl)
#> # A tibble: 4 x 3
#>   cyl       n percent
#>   <fct> <dbl> <chr>  
#> 1 4        11 34.4%  
#> 2 6         7 21.9%  
#> 3 8        14 43.8%  
#> 4 Total    32 100.0%

# variable list to apply function to
vars_list <- c("cyl", "am", "vs")

# using map produces this error
map(vars_list, ~quick_tab(mtcars, all_of(.x)))
#> Error: The LHS of `:=` must be a string or a symbol

Created on 2021-11-23 by the reprex package (v2.0.0)

1 Like

I think either dropping all_of() from your construction (and ignoring the warning) or adding double bangs will fix it.

map(vars_list, ~quick_tab(mtcars, .x))
map(vars_list, ~quick_tab(mtcars, !!all_of(.x)))

Many thanks for your quick reply. Both solutions get rid of the error message, but don't quite produce the intended result, as shown below. Any ideas?

# without all_of adds a new column and doesn't convert the intended column to a factor
# warning message removed
map(vars_list, ~quick_tab(mtcars, .x))

#> [[1]]
#> # A tibble: 4 x 4
#>   cyl       n percent .x   
#>   <chr> <dbl> <chr>   <fct>
#> 1 4        11 34.4%   cyl  
#> 2 6         7 21.9%   cyl  
#> 3 8        14 43.8%   cyl  
#> 4 Total    32 100.0%  cyl  
#> 
#> [[2]]
#> # A tibble: 3 x 4
#>   am        n percent .x   
#>   <chr> <dbl> <chr>   <fct>
#> 1 0        19 59.4%   am   
#> 2 1        13 40.6%   am   
#> 3 Total    32 100.0%  am   
#> 
#> [[3]]
#> # A tibble: 3 x 4
#>   vs        n percent .x   
#>   <chr> <dbl> <chr>   <fct>
#> 1 0        18 56.2%   vs   
#> 2 1        14 43.8%   vs   
#> 3 Total    32 100.0%  vs

# when adding the double bangs I lose the value "labels" for each of the factor levels
map(vars_list, ~quick_tab(mtcars, !!all_of(.x)))
#> [[1]]
#> # A tibble: 4 x 3
#>   cyl       n percent
#>   <fct> <dbl> <chr>  
#> 1 cyl      11 34.4%  
#> 2 cyl       7 21.9%  
#> 3 cyl      14 43.8%  
#> 4 cyl      32 100.0% 
#> 
#> [[2]]
#> # A tibble: 3 x 3
#>   am        n percent
#>   <fct> <dbl> <chr>  
#> 1 am       19 59.4%  
#> 2 am       13 40.6%  
#> 3 am       32 100.0% 
#> 
#> [[3]]
#> # A tibble: 3 x 3
#>   vs        n percent
#>   <fct> <dbl> <chr>  
#> 1 vs       18 56.2%  
#> 2 vs       14 43.8%  
#> 3 vs       32 100.0%

ok, i think we need to force the strings to symbols as part of it.

map(vars_list, ~quick_tab(mtcars, !!sym(.x)))

I'd like the variables/columns (e.g., cyl, am, vs) converted to a factor while preserving the original "labels," as in the below, where cyl is a factor with 4, 6, 8, and Total as levels:

mtcars %>% 
  quick_tab(cyl)
#> # A tibble: 4 x 3
#>   cyl       n percent
#>   <fct> <dbl> <chr>  
#> 1 4        11 34.4%  
#> 2 6         7 21.9%  
#> 3 8        14 43.8%  
#> 4 Total    32 100.0%

Ah, just saw this. It works. Thanks so much.

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.