0

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.

ibm
  • 744
  • 7
  • 14

1 Answers1

1

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.

Emman
  • 3,695
  • 2
  • 20
  • 44
  • Yes, I see, it wasn't working because I was assuming the structure needed to be fct_relevel("c", "d", "b", "a"). Can someone chime in with why it isn't declared in the usual function format? – ibm Jul 25 '21 at 17:36
  • @ibm, see my added section. Does it answer your question? – Emman Jul 25 '21 at 17:41
  • Yes, I think I was probably closing c() after the variables were declared, and that's why when I tried options 2 and 3 on my own I was getting an error about the formula formatting. Thanks for putting these alternatives together. – ibm Jul 25 '21 at 18:19