剪辑R中最小和最大允许值之间的值

Tom*_*ers 17 r vectorization clip clamp

在Mathematica中有一个命令Clip[x, {min, max}] ,它给出了xfor min<=x<=max,minfor x<minmaxfor x>max,以及

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

在R中实现这一目标的最快方法是什么?理想情况下,它应该是一个可列表的函数,理想情况下应该可以处理单个值,向量,矩阵或数据帧......

汤姆,欢呼声

Rom*_*ois 20

Rcppclamp这个:

cppFunction('NumericVector rcpp_clip( NumericVector x, double a, double b){
    return clamp( a, x, b ) ;
}')
Run Code Online (Sandbox Code Playgroud)

这是一个快速基准测试,显示它如何与所讨论的其他方法相比:

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    
Run Code Online (Sandbox Code Playgroud)


42-*_*42- 17

这是一个嵌套pminpmax设置边界的方法:

 fenced.var <- pmax( LB, pmin( var, UB))
Run Code Online (Sandbox Code Playgroud)

很难找到更快的方法.包含在默认范围为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
Run Code Online (Sandbox Code Playgroud)

  • 你的'很难找到更快的方法'显然促使我去看看. (2认同)

Jos*_*ien 8

这是一个适用于矢量和矩阵的函数.

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
Run Code Online (Sandbox Code Playgroud)

这是另一个:

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
Run Code Online (Sandbox Code Playgroud)

  • 这应该在 R 的基础库中! (2认同)