-1

In itself the function works, but I am trying to loop through all the columns in the data, I know using ~apply() works and would love your help on using this thanks.

library(scales)

factorVars <- select_if(df, is.factor)


## function to tidy up to a summary table
tidy_eval_arrange <- function(.data, var) {
  tidydata <- .data %>%
    count({{var}}) %>%
    mutate(pct = n / sum(n),
           pctlabel = paste0(round(pct * 100), "%")) 
  
  print(tidydata)
}

## The issue is here, prints without calculating the percentage properly.
nm <- names(factorVars)
for(i in seq_along(nm)){
  tidy_eval_arrange(df, nm[i])
}
  • What is `df`? Could you please include some example data so that we can [reproduce](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) your problem? – Joe Roe Feb 19 '21 at 09:13
  • Hi @Joe Roe, df is the dataframe we would be testing from. – afrologicinsect Feb 22 '21 at 07:17

2 Answers2

1

You are passing string in the for loop and {{}} does not work with strings (as expected).

tidy_eval_arrange <- function(.data, var) {
  tidydata <- .data %>%
    count({{var}}) %>%
    mutate(pct = n / sum(n),
           pctlabel = paste0(round(pct * 100), "%")) 
  
  print(tidydata)
}
tidy_eval_arrange(mtcars, "cyl")

#   "cyl"  n pct pctlabel
#1   cyl 32   1     100%

{{}} is used for unquoted variables. This works as expected.

tidy_eval_arrange(mtcars, cyl)

#  cyl  n     pct pctlabel
#1   4 11 0.34375      34%
#2   6  7 0.21875      22%
#3   8 14 0.43750      44%

For your code to work in for loop change the function to

tidy_eval_arrange <- function(.data, var) {
  tidydata <- .data %>%
    count(.data[[var]]) %>%
    mutate(pct = n / sum(n),
           pctlabel = paste0(round(pct * 100), "%")) 
  
  print(tidydata)
}
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
0

We could pass either string or unquoted if we convert to symbol with ensym and evaluate (!!)

library(dplyr)
tidy_eval_arrange <- function(.data, var) {
 tidydata <- .data %>%
    count(!! ensym(var)) %>%
   mutate(pct = n / sum(n),
       pctlabel = paste0(round(pct * 100), "%")) 

  print(tidydata)
 }

-testing (tested on dplyr 1.0.4 version)

tidy_eval_arrange(mtcars, "cyl")
#  cyl  n     pct pctlabel
#1   4 11 0.34375      34%
#2   6  7 0.21875      22%
#3   8 14 0.43750      44%
      
tidy_eval_arrange(mtcars, cyl)
#  cyl  n     pct pctlabel
#1   4 11 0.34375      34%
#2   6  7 0.21875      22%
#3   8 14 0.43750      44%
akrun
  • 874,273
  • 37
  • 540
  • 662