Значения клипов между минимальным и максимальным допустимым значением в R
В Mathematica есть команда Clip[x, {min, max}]
который дает x
для min<=x<=max
, min
для x<min
и max
для x>max
, см.
http://reference.wolfram.com/mathematica/ref/Clip.html (mirror)
Каким будет самый быстрый способ достичь этого в R? В идеале это должна быть функция, которая может быть перечислимой, и в идеале должна работать либо с одним значением, вектором, матрицей или с файловой рамкой...
веселит,
Том
Ответы
Ответ 1
Rcpp
имеет clamp
для этого:
cppFunction('NumericVector rcpp_clip( NumericVector x, double a, double b){
return clamp( a, x, b ) ;
}')
Ниже приведен быстрый тест, показывающий, как он работает против других обсуждаемых методов:
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
Ответ 2
Здесь метод с вложенными pmin
и pmax
настройками границ:
fenced.var <- pmax( LB, pmin( var, UB))
Трудно найти метод, который быстрее. Завершена функция, которая по умолчанию имеет диапазон 3 и 7:
fence <- function(vec, UB=7, LB=3) pmax( LB, pmin( vec, UB))
> fence(1:10)
[1] 3 3 3 4 5 6 7 7 7 7
Ответ 3
Здесь одна функция, которая будет работать как для векторов, так и для матриц.
myClip <- function(x, a, b) {
ifelse(x <= a, a, ifelse(x >= b, b, x))
}
myClip(x = 0:10, a = 3,b = 7)
# [1] 3 3 3 3 4 5 6 7 7 7 7
myClip(x = matrix(1:12/10, ncol=4), a=.2, b=0.7)
# myClip(x = matrix(1:12/10, ncol=4), a=.2, b=0.7)
# [,1] [,2] [,3] [,4]
# [1,] 0.2 0.4 0.7 0.7
# [2,] 0.2 0.5 0.7 0.7
# [3,] 0.3 0.6 0.7 0.7
И вот еще:
myClip2 <- function(x, a, b) {
a + (x-a > 0)*(x-a) - (x-b > 0)*(x-b)
}
myClip2(-10:10, 0, 4)
# [1] 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 4 4 4 4 4 4
Ответ 4
Я считаю, что clamp()
из пакета raster
.
library(raster)
clamp(x, lower=-Inf, upper=Inf, ...)