I wonder why my_function() below doesn’t arrange_by= the variable given to it?
For example, try: my_function(DATA, study, time, treat_grp, arrange_by = "treat_grp") OR
my_function(DATA, study, time, treat_grp, arrange_by = "time") and there is no arranging happening.
Is there any fix to this?
library(tidyverse)
my_function <- function(data, cluster, ..., arrange_by = NULL){
cluster <- rlang::ensym(cluster)
cat_mod <- rlang::ensyms(...)
cat_nms <- purrr::map_chr(cat_mod, rlang::as_string)
data %>%
count(!!cluster, !!!rlang::syms(cat_nms)) %>%
group_by(!!!rlang::syms(cat_nms)) %>%
summarize(`n study` = n(),
`n effect` = sum(n)) %>%
ungroup() %>%
tidyr::complete(!!!rlang::syms(cat_nms), fill = list(`n study` = 0, `n effect` = 0)) %>%
arrange(if(is.null(arrange_by)) all_of(cat_nms[1]) else all_of(arrange_by))
}
#--------------------------------------------------
DATA <- structure(list(study = c(1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 4, 4,
4, 5, 5), time = c("baseline", "posttest1", "posttest2", "baseline",
"posttest1", "posttest2", "posttest1", "posttest1", "posttest1",
"posttest1", "posttest1", "posttest1", "posttest1", "posttest1",
"posttest2"), treat_grp = c("conventional", "conventional", "conventional",
"conventional", "conventional", "conventional", "conventional",
"framework_notes", "conventional", "conventional", "conventional",
"conventional", "conventional", "vocabulary_notebook", "vocabulary_notebook"
)), row.names = c(NA, -15L), class = "data.frame")
>Solution :
You need to use across() with your arrange() or arrange_at() line. For example
arrange(across(if(is.null(arrange_by)) all_of(cat_nms[1]) else all_of(arrange_by)))
# or
arrange_at(if(is.null(arrange_by)) all_of(cat_nms[1]) else all_of(arrange_by))
With a simpler example
iris %>% arrange(Sepal.Width) %>% head()
iris %>% arrange(all_of("Sepal.Width")) %>% head()
iris %>% arrange(across(all_of("Sepal.Width"))) %>% head()
iris %>% arrange_at("Sepal.Width") %>% head()
You can see the arrange only works for lines 1 3 and 4, not 2.