Search code examples
rdplyrcase-whenforcats

dplyr::case_when giving warnings about RHS of cases which should not be evaluated


I have a tibble where one column is an ordered factor containing the names of the components of a decomposed time series; I want to change these because they are not easily comprehensible ("level" is not to my mind as clear as "trend", and "weekly" and "annual" are better names than "season1" and "season2").

Sometimes I get "season1" and "season2", but sometimes just "season". I am using dplyr::mutate, dplyr::case_when and forcats::fct_recode. In the case where the first option of the case_when statement matches, I would expect that it would pay no attention to any of the others.

However, in the case when I am testing for a given level and then changing the name of that same level, it is throwing a warning

"Warning: Unknown levels in f"

about the level changed in the next case. I know it's only a warning and the output is right, but it is annoying me and I want to know what I did wrong.

I am using dplyr 0.8.0.1 and forcats 0.4.0 on R 3.4.4.

# This throws a warning about unknown levels: a

library(dplyr)
library(forcats)

d <- tibble(a = 1:3, b = as.ordered(c("ab", "d", "e")))

d %>%
  mutate(b = case_when(
    "ab" %in% levels(b) ~ fct_recode(b, foo = "ab"),
    "a" %in% levels(b) ~ fct_recode(b, bar = "a"),
    TRUE ~ b
  ))
# This doesn't generate a warning

library(dplyr)
library(forcats)

d <- tibble(a = 1:3, b = as.ordered(c("ab", "d", "e")))

d %>%
  mutate(b = case_when(
    "ab" %in% levels(b) ~ fct_recode(b, foo = "ab"),
    "a" %in% levels(b) ~ fct_recode(b, bar = "d"),
    TRUE ~ b
  ))

Expected result: b has levels "foo", "d" and "e" with no complaints.

Actual result: levels correct, but "## Warning: Unknown levels in f: a"


Solution

  • That's because case_when executes all of the right-hand sides (RHS) and then keeps everything that satisfies left-hand side (LHS).

    case_when will evaluate fct_recode(b, bar = "a") even when "a" %in% levels(b) is FALSE. That's why it gives a warning.

    mishabalyasin, from comunity.rstudio.com, found the answer. See here.