Tom Wenseleers - 2 years ago 77
R Question

# Clip values between a minimum and maximum allowed value in R

In Mathematica there is the command

`Clip[x, {min, max}]`

which gives
`x`
for
`min<=x<=max`
,
`min`
for
`x<min`
and and
`max`
for
`x>max`
, see

http://reference.wolfram.com/mathematica/ref/Clip.html (mirror)

What would be the equivalent command for this in R? Ideally it should be a function that is listable, and that would either take a single value, or vector or a matrix as an argument?
I'm sure it must be easy, but I just couldn't find it anywhere... (and my own function I wrote to do this is a bit slow)

cheers,
Tom

`Rcpp` has `clamp` for this:

``````cppFunction('NumericVector rcpp_clip( NumericVector x, double a, double b){
return clamp( a, x, b ) ;
}')
``````

Here is a quick benchmark showing how it performs against other methods discussed :

``````pmin_pmax_clip <- function(x, a, b) pmax(a, pmin(x, b) )
ifelse_clip <- function(x, a, b) {
ifelse(x <= a,  a, ifelse(x >= b, b, x))
}
operations_clip <- function(x, a, b) {
a + (x-a > 0)*(x-a) - (x-b > 0)*(x-b)
}
x <- rnorm( 10000 )
require(microbenchmark)

microbenchmark(
pmin_pmax_clip( x, -2, 2 ),
rcpp_clip( x, -2, 2 ),
ifelse_clip( x, -2, 2 ),
operations_clip( x, -2, 2 )
)
# Unit: microseconds
#                        expr      min        lq   median        uq       max
# 1     ifelse_clip(x, -2, 2) 2809.211 3812.7350 3911.461 4481.0790 43244.543
# 2 operations_clip(x, -2, 2)  228.282  248.2500  266.605 1120.8855 40703.937
# 3  pmin_pmax_clip(x, -2, 2)  260.630  284.0985  308.426  336.9280  1353.721
# 4       rcpp_clip(x, -2, 2)   65.413   70.7120   84.568   92.2875  1097.039
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download