Is there a shorter way to select elements and modify them? For example, in
y[y < 1] <- y[y < 1]*2
the object y is referenced 4 times in one line. Is it possible to reduce this repetition?
Here's a construct that reduces the number of references to y
by 1:
y <- -2:2
y[i] <- y[i <- y < 1] * 10
y
# [1] -20 -10 0 1 2
In practice, though, I'm more likely to do this, which is maybe less "clever" but is certainly much easier to parse (for a human):
i <- y < 2
y[i] <- y[i] * 10
Try this
y <- y*{{y<1} + 1}
In general you can introduce a function f
f <- function(bool) ifelse(bool, 2, 1)
y <- y * f(y < 1)
This approach seems a bit faster than Josh's solution
n <- 10000
y <- sample(c(1,-1), n, replace = TRUE)
f1 <- function(y){y[i] <- y[i <- y < 1] * 10; y}
f2 <- function(y){y <- y*{{y<1} + 1}; y}
benchmark(f1(y), f2(y), replications = 50000)
test replications elapsed relative user.self sys.self user.child sys.child 1 f1(y) 50000 30.29 2.398 27.427 3.146 0 0 2 f2(y) 50000 12.63 1.000 9.859 2.918 0 0
This does not reduce the number of references to y
, but it does stop y>1
being calculated twice
y <- ifelse(y<1, y, y *2)
or you could predefine y <1
replacing <- y < 1
Then the line only contains two explicit references to y
y[replacing] <- y[replacing] *2
You could put y in a data.table
, and then you can (almost) reduce the number of times y
is repeated by 1
library(data.table)
Y <- data.table(y = y)
Y[y <1, y := y*2]
I say almost, because if you want to access the atomic vector y
, you will need to type Y[,y]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With