I need to project values (x) between 0 and 1 to a w shape (y=f(x)):

I can achieve what I need with the following function:
f <- function(x) {
if (x < 0.25) {
return (1-4*x)
}
if (x < 0.50) {
return (-1 + 4*x)
}
if (x < 0.75) {
return (3 - 4*x)
}
return (-3 + 4*x)
}
x <- 0:20/20
y <- lapply(x, f)
plot(x, y)
lines(x,y, col='red')
However, I am inclined to believe that there is a more elegant solution, possibly a one liner, to my problem.
Is there such a thing in R?
f <- function(x)
abs(abs(2 - 4 * x) - 1)
plot(f)

Here is a vectorised solution.
f2 <- function(x) {
y <- 1 - 4 * x
y[0.25 <= x & x < 0.50] <- -1 + 4 * x[0.25 <= x & x < 0.50]
y[0.50 <= x & x < 0.75] <- 3 - 4 * x[0.50 <= x & x < 0.75]
y[0.75 <= x] <- -3 + 4 * x[0.75 <= x]
return(y)
}
This has the benefit that it is much faster
x <- seq(0, 1, length = 1001)
library(microbenchmark)
microbenchmark(
original = {y1 <- sapply(x, f)},
vectorised = {y2 <- f2(x)}
)
all.equal(y1, y2)
The timings
Unit: microseconds
expr min lq mean median uq max neval cld
original 1170.487 1198.0590 1500.39726 1534.2840 1566.953 8317.288 100 b
vectorised 51.767 55.2405 58.65856 56.9055 58.981 107.117 100 a
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