Clamp variable within range

Given two values x and b, I want a function to clamp x to fall within [-b, b]. In particular:

  • If x is less than or equal to -b, then the function returns -b;
  • If x is greater than -b and less than b, then the function returns x;
  • If 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)

2 Answers

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.

0

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

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like