I want to create a function with 3 arguments: df (dataframe) and 2 variables. And return a cross table. I can do it easily outside a function using tabyl
. But how to do it using a function where I can select df
and the 2 variables?
I suspect that this is a case of non-standard evaluation...
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(janitor)
#>
#> Attaching package: 'janitor'
#> The following objects are masked from 'package:stats':
#>
#> chisq.test, fisher.test
mtcars %>%
janitor::tabyl(vs, cyl)
#> vs 4 6 8
#> 0 1 3 14
#> 1 10 4 0
# How can I put this into a function?
crTab <- function(df, v1, v2) {
t <- df %>%
tabyl(all_of(v1), all_of(v2))
return(t)
}
crTab('mtcars', 'vs', 'cyl')
#> Error in tabyl.default(., all_of(v1), all_of(v2)): The value supplied to the "show_na" argument must be TRUE or FALSE.
#>
#> Did you try to call tabyl on two vectors, like tabyl(data$var1, data$var2) ? To create a two-way tabyl, the two vectors must be in the same data.frame, and the function should be called like this:
#>
#> tabyl(data, var1, var2)
#> or
#> data %>% tabyl(var1, var2).
#>
#> See ?tabyl for more.
CodePudding user response:
If you want to pass column names in tidyverse setting use double curly brackets:
"‘rlang’ uses NSE to capture the unevaluated argument and then checks whether the parse tree of the expression contains two nested { calls. It then takes the unevaluated expression and transforms it appropriately." taken from @Konrad Rudolph https://stackoverflow.com/questions/69454090/how-is-rlangs-curly-curly-operator-implemented#:~:text=The curly-curly operator {{,such as the data frame.
library(dplyr)
library(janitor)
crTab <- function(df, v1, v2) {
t <- df %>%
tabyl({{v1}}, {{v2}})
return(t)
}
crTab(mtcars, vs, cyl)
vs 4 6 8
0 1 3 14
1 10 4 0