Given two values x
and b
, I want a function to clamp x
to fall within [-b, b]
. In particular:
x
is less than or equal to -b
, then the function returns -b
;x
is greater than -b
and less than b
, then the function returns x
;x
is greater than or equal to b
, then the function returns b
.In R I wrote the following function truncfn
. Only part of this function works. Where did I make mistake? Is there an easier way to do this?
b <- 5
truncfn <- function(x){
if((x<(-b))||(x==-b)) -b
if((x>(-b))&&(x<b)) x
if((x>b)||(x==b)) b
}
truncfn(10)
5
truncfn(4)
truncfn(-10)
I would use the pmin
and pmax
functions to do this is a single expression without if
statements:
b <- 5
x <- seq(-10, 10)
pmax(pmin(x, b), -b)
# [1] -5 -5 -5 -5 -5 -5 -4 -3 -2 -1 0 1 2 3 4 5 5 5 5 5 5
You could have fixed your function by replacing the second and third if
statements with else if
statements (or alternately using return(b)
, return(x)
and return(-b)
). Here is a working version (I've taken the liberty to use <=
instead of separately checking with <
and ==
):
truncfn <- function(x){
if (x <= -b) -b
else if (x > -b && x < b) x
else b
}
truncfn(10)
# [1] 5
truncfn(4)
# [1] 4
truncfn(-10)
# [1] -5
However note that the function I wrote with pmin
and pmax
can take a whole vector as input, while yours is limited to taking a single number.
You can use raster::clamp
library(raster)
b <- 5
v <- -10:10
raster::clamp(v, -b, b)
# [1] -5 -5 -5 -5 -5 -5 -4 -3 -2 -1 0 1 2 3 4 5 5 5 5 5 5
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