Thanks for the interesting puzzle, @Andrea!
You can think of each ~
expression in case_when()
as applying replace()
to a logical vector:
x <- c(1, 3)
bool <- sample(c(T, F), 8, replace = T)
bool
#> [1] TRUE FALSE TRUE FALSE FALSE TRUE TRUE TRUE
replace(bool, bool, which(bool))
#> [1] 1 0 3 0 0 6 7 8
case_when(bool ~ 1:8)
#> [1] 1 NA 3 NA NA 6 7 8
with the difference that case_when()
--- as a 'tidy' function --- requires that the replacement vector be of the same length as bool
(or of length 1, and then recycled to the length of bool
).
In the case of RMSE_table
, since the replacement vector, x
, is of length 2, the group_by()
command is necessary so that the vector
model == "exponential" & type == "cumulative"
is also of length 2, since each subtable created by group_by(model, type)
has exactly two rows:
library(tidyverse)
RMSE_table <-
data.frame(
model = rep(c("exponential", "polynomial"), times = 4),
type = rep(c("cumulative","new"), each = 4),
data = rep(rep(c("cases","deaths"), each = 2), times = 2),
RMSE = numeric(8)
)
RMSE_table %>%
count(model, type)
#> # A tibble: 4 x 3
#> model type n
#> <fct> <fct> <int>
#> 1 exponential cumulative 2
#> 2 exponential new 2
#> 3 polynomial cumulative 2
#> 4 polynomial new 2
@Yarnabrina's replace()
solution is more general, but doesn't work if the logical vector contains an NA
:
RMSE_table %>%
add_row(RMSE = 0)
#> model type data RMSE
#> 1 exponential cumulative cases 0
#> 2 polynomial cumulative cases 0
#> 3 exponential cumulative deaths 0
#> 4 polynomial cumulative deaths 0
#> 5 exponential new cases 0
#> 6 polynomial new cases 0
#> 7 exponential new deaths 0
#> 8 polynomial new deaths 0
#> 9 <NA> <NA> <NA> 0
RMSE_table %>%
add_row(RMSE = 0) %>%
mutate(
RMSE =
replace(x = RMSE,
list = model == "exponential" & type == "cumulative",
values = c(1, 3)
)
)
#> Error in x[list] <- values: NAs are not allowed in subscripted assignments
A more general version of the solution I posted is possible if the issues caused by the length of x
can be circumvented:
RMSE_table %>%
# add_row(RMSE = 0) %>%
group_by(model, type) %>%
mutate(
RMSE =
case_when(
model == "exponential" & type == "cumulative" ~
x[1:n()],
TRUE ~ RMSE
)
)
#> # A tibble: 8 x 4
#> # Groups: model, type [4]
#> model type data RMSE
#> <fct> <fct> <fct> <dbl>
#> 1 exponential cumulative cases 1
#> 2 polynomial cumulative cases 0
#> 3 exponential cumulative deaths 3
#> 4 polynomial cumulative deaths 0
#> 5 exponential new cases 0
#> 6 polynomial new cases 0
#> 7 exponential new deaths 0
#> 8 polynomial new deaths 0
RMSE_table %>%
add_row(RMSE = 0) %>%
group_by(model, type) %>%
mutate(
RMSE =
case_when(
model == "exponential" & type == "cumulative" ~
x[1:n()],
TRUE ~ RMSE
)
)
#> Warning: Factor `model` contains implicit NA, consider using
#> `forcats::fct_explicit_na`
#> # A tibble: 9 x 4
#> # Groups: model, type [5]
#> model type data RMSE
#> <fct> <fct> <fct> <dbl>
#> 1 exponential cumulative cases 1
#> 2 polynomial cumulative cases 0
#> 3 exponential cumulative deaths 3
#> 4 polynomial cumulative deaths 0
#> 5 exponential new cases 0
#> 6 polynomial new cases 0
#> 7 exponential new deaths 0
#> 8 polynomial new deaths 0
#> 9 <NA> <NA> <NA> 0
Created on 2020-03-27 by the reprex package (v0.3.0)