The solution to piping fct_relevel to mutate a subset of variables no longer works since mutate_at has been deprecated. I'm having a tough time piecing together an updated solution using mutate(across(...), fct_relevel(., ....)
, since I get an error that
"Problem with `mutate()` input `..2`.
i `..2 = ~...`.
x `..2` must be a vector, not a `formula` object."
but there is no formula
Let's say I have
f1 <- factor(c("a", "b", "c", "d"))
g2 <- factor(c("a", "b", "c", "d"))
t3 <- factor(c("a", "b", "c", "d"))
f5 <- factor(c("m", "l", "f", "p"))
y8 <- factor(c("a", "b", "c", "d"))
df <- tibble(f1, g2, t3, f5, y8)
and I want to fct_relevel
f1, g2, and y8 (so non-sequential variables) so that you have the factors ordered as "c", "d", "b", "a" for all three of these variables.
Probably this:
library(dplyr) # 1.0.7
library(forcats) # 0.5.1
f1 <- factor(c("a", "b", "c", "d"))
g2 <- factor(c("a", "b", "c", "d"))
t3 <- factor(c("a", "b", "c", "d"))
f5 <- factor(c("m", "l", "f", "p"))
y8 <- factor(c("a", "b", "c", "d"))
df <- tibble(f1, g2, t3, f5, y8)
df_1 <- df %>%
mutate(across(c(f1, g2, y8), forcats::fct_relevel, "c", "d", "b", "a"))
levels(df$f1)
#> [1] "c" "d" "b" "a"
levels(df$g2)
#> [1] "c" "d" "b" "a"
levels(df$t3)
#> [1] "a" "b" "c" "d"
levels(df$f5)
#> [1] "f" "l" "m" "p"
levels(df$y8)
#> [1] "c" "d" "b" "a"
Created on 2021-07-25 by the reprex package (v2.0.0)
Below I add two more syntaxes that are equivalent to the one above.
# option 2
df_2 <- df %>%
mutate(across(c(f1, g2, y8), ~forcats::fct_relevel(., "c", "d", "b", "a")))
# option 3
df_3 <- df %>%
mutate(across(c(f1, g2, y8), ~forcats::fct_relevel(.x, "c", "d", "b", "a")))
identical(df_1, df_2) # TRUE
identical(df_1, df_3) # TRUE
The way the above fct_relevel()
operates is that it treats each column (i.e., f1
, g2
, y8
) as a vector passed to fct_relevel
, plugged in instead of the .
or .x
. It "knows" to do such "plugging" because we use the ~
right before the function.