【问题标题】:Clip values between a minimum and maximum allowed value in R在 R 中的最小和最大允许值之间剪辑值
【发布时间】:2012-12-01 21:08:39
【问题描述】:

在 Mathematica 中有命令Clip[x, {min, max}] 这给出了x 用于min<=x<=maxmin 用于x<minmax 用于x>max,请参阅

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

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

【问题讨论】:

    标签: r vectorization clip clamp


    【解决方案1】:

    我相信那会是来自raster 包的clamp()

    library(raster)
    clamp(x, lower=-Inf, upper=Inf, ...)
    

    【讨论】:

      【解决方案2】:

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

       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
      

      【讨论】:

      • 非常优雅——太好了!
      • 我经常使用这个。我有一个大型数据集,其中有几个变量在 0 以下似乎不太真实,并且在高端也应该受到合理的限制。真正的诀窍是记住用pmin 设置最大值,用pmax 设置最小值。
      • 您的“很难找到更快的方法”显然促使我去看看。
      • 是的。到目前为止,它仍然赢得了紧凑性奖。
      • 我认为函数的参数 UB 和 LB 应该颠倒过来。我怀疑fence &lt;- function(vec, LB=3, UB=7) pmax( LB, pmin( vec, UB)) 真的是你所追求的
      【解决方案3】:

      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    
      

      【讨论】:

      • 那个时代真是太棒了。
      • 只是在控制台会话中粘贴钳位代码的行显然不是您希望我们 Rcpp 处女做的事情。
      • 差不多。在我的编辑中查看我对cppFunction 的使用。 (但您需要Rcpp 的当前开发版本,因为clamp 自上次发布以来已修复)。
      • 非常酷。我对operations_clip() 时代的糟糕程度感到震惊和困惑....有时。任何想法为什么 max 值比所有这些函数的 min 值大得多?
      • 我很确定这是关于内存分配的。 operations_clip 执行了很多,所以我猜有时需要更长的时间。
      【解决方案4】:

      这是一个适用于向量和矩阵的函数。

      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
      

      【讨论】:

      • 太棒了!非常感谢!!我的功能要慢得多,但它的工作速度非常快!
      • 这应该在 R 的基础库中!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-19
      • 1970-01-01
      相关资源
      最近更新 更多