mercredi 5 février 2020

Vectorized if_else or case_when which doesn't eagerly evaluate its potential outputs?

dplyr has the vectorized conditionals if_else and case_when.

However, both of these eagerly evaluate their possible outputs (true/false for if_else, the RHS of the formula for case_when):

suppressPackageStartupMessages({
  library(dplyr)
})

if_else(c(T, T, T), print(1), print(2))
#> [1] 1
#> [1] 2
#> [1] 1 1 1

case_when(
  c(T, T, T) ~ print(1),
  c(F, F, F) ~ print(2)
)
#> [1] 1
#> [1] 2
#> [1] 1 1 1

Created on 2020-02-05 by the reprex package (v0.3.0)

Here we can obviously see the false cases are evaluated even though they're never used. I'm looking for a way to avoid this since my

Is there an alternative which doesn't do this?

I'm aware, one alternative is actually base::ifelse:

ifelse(c(T, T, T), print(1), print(2))
#> [1] 1
#> [1] 1 1 1

However base::ifelse is notoriously inefficient, so a better alternative would be nice. That being said, I'm especially interested in alternatives for case_when, which I use quite a bit when I'd otherwise need to use a chain of ifelses.

I've already looked at data.table::fifelse, but it suffers from the same problem:

suppressPackageStartupMessages({
  library(data.table)
})

fifelse(c(T, T, T), print(1), print(2))
#> [1] 1
#> [1] 2
#> [1] 1 1 1

So, is there an alternative for if_else and case_when which doesn't eagerly evaluate its unused cases?

Aucun commentaire:

Enregistrer un commentaire