Reputation: 101
I am trying to write a function to dynamically group_by every combination of a character vector.
This is how I set it up my list:
stuff <- c("type", "country", "color")
stuff_ListStr <- do.call("c", lapply(seq_along(stuff), function(i) combn(stuff, i, FUN = list)))
stuff_ListChar <- sapply(stuff_ListStr, paste, collapse = ", ")
stuff_ListSym <- lapply(stuff_ListChar, as.symbol)
Then I threw it into a loop.
b <- list()
for (each in stuff_ListSym) {
a <- answers_wfh %>%
group_by(!!each) %>%
summarize(n=n())
b <- append(b, a)
}
So essentially I want to replicate this
... group_by(type),
... group_by(country),
... group_by(type, country),
... and the rest of the combinations. Then I want put all the summaries into one list (a list of tibbles/lists)
It's totally failing. This is my error message:
Error: Column `type, country` is unknown
.
Not only that, b
is not giving me what I want. It's a list with length 12 already when I only expected 2 before it failed. One tibble grouped by 'type' and the second by 'country'.
I'm new to R in general but thought tidy eval was really cool and wanted to try. Any tips here?
Upvotes: 0
Views: 178
Reputation: 389165
I think stuff_ListStr
is enough to get what you want. You cold use group_by_at
which accepts character vector.
library(dplyr)
library(rlang)
purrr::map(stuff_ListStr, ~answers_wfh %>% group_by_at(.x) %>% summarize(n=n()))
A better option is to use count
but count does not accept character vectors so using some non-standard evaluation.
purrr::map(stuff_ListStr, ~answers_wfh %>% count(!!!syms(.x)))
Upvotes: 1
Reputation: 6226
I think you have a problem of standard evaluation. !!
is sometimes not enough to unquote variables and get dplyr
to work. Use !!!
and rlang::syms
for multiple unquotes
b <- list()
for (each in stuff_ListSym) {
a <- answers_wfh %>%
group_by(!!!rlang::syms(each)) %>%
summarize(n=n())
b <- append(b, a)
}
I think lapply
would be better in your situation than for
since you want to end-up with a list
Since you use variable names as arguments of functions, you might be more comfortable with data.table
than dplyr
. If you want the equivalent data.table
implementation:
library(data.table)
setDT(answers_wfh)
lapply(stuff_ListSym, function(g) answers_wfh[,.(n = .N), by = g])
You can have a look at this blog post I wrote on the subject of SE vs NSE in dplyr
and data.table
Upvotes: 3