To address whether or not it is bad coding style, that would depend if the project to which you are contributing already has an existing style guide or not. If not, then so long as you are comfortable that is fine. I would recommend adding a comment to the source code noting that you are taking advantage of R's interpreting TRUE
and FALSE
as 1
and 0
respectively for the next coder (which is usually you in six weeks!).
As for timing, here are some tests which show that in a simple case, the implicit conversion is the fastest, followed by R base naturally vectorized ifelse
followed by dplyr
. If your data is actually huge, you may also want to consider using data.table
.
DF <- data.frame(
x = c(TRUE, FALSE, FALSE, TRUE),
y = c(100, 100, 140, 180)
)
library(microbenchmark)
MB <- microbenchmark(DF$z <- DF$y + 500 * !DF$x,
DF$z <- dplyr::if_else(!DF$x, DF$y + 500, DF$y),
DF$z <- ifelse(!DF$x, DF$y + 500, DF$y),
DF$z <- DF$y + ifelse(!DF$x, 500, 0),
control = list(order = 'block'),
check = 'identical',
setup = "DF$z <- NULL",
times = 1000L)
print(MB, order = "median")
Unit: microseconds
expr min lq mean median uq max neval cld
DF$z <- DF$y + 500 * !DF$x 6.6 6.9 7.0910 6.9 7.10 31.6 1000 a
DF$z <- DF$y + ifelse(!DF$x, 500, 0) 9.5 9.8 10.4312 10.0 10.30 31.4 1000 a
DF$z <- ifelse(!DF$x, DF$y + 500, DF$y) 10.7 11.1 11.5493 11.3 11.50 67.8 1000 a
DF$z <- dplyr::if_else(!DF$x, DF$y + 500, DF$y) 96.1 98.5 115.6216 103.0 128.85 3411.8 1000 b