Reputation: 399
I am trying to use the group_by function inside of a function but it doesn't seem to work. I found an example in another post as below (this works) :-
dat <- mtcars[c(2:4,11)]
grp <- function(x) {
group_by(dat,!!as.name(x)) %>%
summarise(n=n()) %>%
mutate(pc=scales::percent(n/sum(n))) %>%
arrange(desc(n)) %>% head()
}
lapply(colnames(dat), grp)
What I don't understand is why do I need to data frame name in the group_by function - doesn't group_by function work this way :-
data %>% group_by(lgID) %>% summarise(mean_run = mean(HR))
where the data is piped to the group_by function?
Also, why do I need '!!as.name(x)' - what does this do?
Further, why does the version shown above work and this version shown below doesn't?
grp <- function(x) {
group_by(x) %>%
summarise(n=n()) %>%
mutate(pc=scales::percent(n/sum(n))) %>%
arrange(desc(n)) %>% head()
}
lapply(colnames(dat), grp)
Obviously I am missing something here!
Best regards
Deepak
Upvotes: 0
Views: 121
Reputation: 887951
If we need to pass both index and strings as 'x', wrap it inside across
within group_by
library(dplyr) # version >= 1.0.0
f1 <- function(data, x) {
data %>%
group_by(across(all_of(x))) %>%
summarise(n=n(), .groups = 'drop') %>%
mutate(pc=scales::percent(n/sum(n))) %>%
arrange(desc(n)) %>%
head()
}
If we have an older version, use group_by_at(x)
-apply the function
out1 <- lapply(colnames(dat), function(x) f1(dat, x))
Or use index
out2 <- lapply(seq_along(dat), function(i) f1(dat, i))
identical(out1, out2)
#[1] TRUE
-output
out1[[1]]
# A tibble: 3 x 3
# cyl n pc
# <dbl> <int> <chr>
#1 8 14 43.8%
#2 4 11 34.4%
#3 6 7 21.9%
out2[[1]]
# A tibble: 3 x 3
# cyl n pc
# <dbl> <int> <chr>
#1 8 14 43.8%
#2 4 11 34.4%
#3 6 7 21.9%
Upvotes: 1