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 fastest way to achieve this in R? Ideally it should be a function that is listable, and should ideally work on either a single value, vector, matrix or dataframe...
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
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