`fct_relevel()` should gain `fct_recode()` functionality
Closed this issue · 3 comments
Hi,
Whenever I use fct_relevel()
, I always feel like it should have some of fct_recode()
functionalities:
library(forcats)
x <- fct(c("apple", "bear", "apple", "bear"))
x
#> [1] apple bear apple bear
#> Levels: apple bear
fct_recode(x, animal = "bear", fruit = "apple")
#> [1] fruit animal fruit animal
#> Levels: fruit animal
fct_relevel(x, animal = "bear", fruit = "apple")
#> [1] apple bear apple bear
#> Levels: bear apple
# expected output:
x %>%
fct_recode(animal = "bear", fruit = "apple") %>%
fct_relevel("animal", "fruit")
#> [1] fruit animal fruit animal
#> Levels: animal fruit
Created on 2022-10-17 with reprex v2.0.2
I don't think this could break any existing code, but if this is very unfortunately not achievable, I would at least expect some warning saying that fct_relevel()
is not expecting a named ellipsis.
I think check_dots_unnamed()
is the best option for now. At some point it seems like we should rethink the design of the forcats functions, but now doesn't feel like the time.
@DanChaltiel There was a great function that did exactly what I think you (and a few others) have requested at #45 (comment). We were using it a lot until @hadley's "fix" here broke it, though I admit it did require knowing what you were doing and relied on the fact that the names were passed through unchanged so maybe the news quote is only half unfair.
I can give you this version which is working for me, although it feels a bit more brittle
library(forcats)
fct_reorg = function(fac, ...) {
fct_relevel(fct_recode(fac, ...), names(rlang::dots_list(...)))
}
x <- fct(c("apple", "bear", "apple", "bear"))
x
#> [1] apple bear apple bear
#> Levels: apple bear
fct_recode(x, animal = "bear", fruit = "apple")
#> [1] fruit animal fruit animal
#> Levels: fruit animal
# expected output:
out_pipe = x %>%
fct_recode(animal = "bear", fruit = "apple") %>%
fct_relevel("animal", "fruit")
out_pipe
#> [1] fruit animal fruit animal
#> Levels: animal fruit
# or using the function
out_reorg = fct_reorg(x, animal = "bear", fruit = "apple")
out_reorg
#> [1] fruit animal fruit animal
#> Levels: animal fruit
identical(out_pipe, out_reorg)
#> [1] TRUE
# works with splicing
vars2recode_and_relevel = c(animal = "bear", fruit = "apple")
out_splice = fct_reorg(x, !!!vars2recode_and_relevel)
out_splice
#> [1] fruit animal fruit animal
#> Levels: animal fruit
identical(out_pipe, out_splice)
#> [1] TRUE
Created on 2023-05-15 with reprex v2.0.2
I agree that there should be a forcats function that can do this properly.
Thanks for the function, that will be very helpful :-)
At some point it seems like we should rethink the design of the forcats functions, but now doesn't feel like the time.
I guess we will have to wait a bit more until it becomes part of forcats
though.