• R语言
  • 如何用R语言画分段函数?

假设有这样一个分段函数y = 2(0<x<1),y = 0.1(1<x<2),y = -1(2<x<5)

简单粗暴的写法, 为了X的区间连续加上了x=0,x=1 x=2的边界

f = function(x) {
  sapply(x, function(x) {
    y = numeric()
    if (x >= 0 & x < 1)
      y = 2
    else if (x >= 1 & x < 2)
      y = 0.1
    else if (x >= 2 & x < 5)
      y = -1
    return(y)
  })
}

x = seq(0, 5, 0.1)

plot(x, f(x))

<sup>Created on 2019-01-14 by the reprex package (v0.2.1)</sup>

    tctcabifelse() 会不会更简洁一点?

    x <- seq(-1, 10, 0.1)
    y <- ifelse(x > 0 & x < 1, 2, ifelse(x > 1 & x < 2, 1, ifelse(x > 2 & x < 5, -1, NA)))
    plot(x, y)

      dapengde
      搜了一下还是有好多答案的
      https://stackoverflow.com/questions/8788050/how-to-define-a-piecewise-function-in-r

      ifelse写法是简单,但有一次在so上有小伙伴提示ifelse比较慢之后都在避免用它.


      刚benchmark了一下好像速度并没有可见的差异…

      fun1 = function(){
        f = function(x) {
          sapply(x, function(x) {
            y = numeric()
            if (x >= 0 & x < 1)
              y = 2
            else if (x >= 1 & x < 2)
              y = 0.1
            else if (x >= 2 & x < 5)
              y = -1
            return(y)
          })
        }
        
        x = seq(0, 500, 0.1)
        
        y = f(x)
      }
      
      fun2 = function(){
        x = seq(0, 500, 0.1)
        y = ifelse(x > 0 & x < 1, 2, ifelse(x > 1 & x < 2, 1, ifelse(x > 2 & x < 5, -1, NA)))
      }
      
      fun3 = function(){
        x = seq(0, 500, 0.1)
        y <- (x > 0 & x < 1) * 2 +
            (x > 1 & x < 2) * 1 +
            (x > 2 & x < 5) * -1
      }
      
      microbenchmark::microbenchmark(list = c(fun1,fun2,fun3), times = 10000)
      #> Unit: nanoseconds
      #>                                                                                                                                                                                                                                                                                                                                                             expr
      #>  function ()  {     f = function(x) {         sapply(x, function(x) {             y = numeric()             if (x >= 0 & x < 1)                  y = 2             else if (x >= 1 & x < 2)                  y = 0.1             else if (x >= 2 & x < 5)                  y = -1             return(y)         })     }     x = seq(0, 500, 0.1)     y = f(x) }
      #>                                                                                                                                                                                                                     function ()  {     x = seq(0, 500, 0.1)     y = ifelse(x > 0 & x < 1, 2, ifelse(x > 1 & x < 2, 1, ifelse(x >          2 & x < 5, -1, NA))) }
      #>                                                                                                                                                                                                                                     function ()  {     x = seq(0, 500, 0.1)     y <- (x > 0 & x < 1) * 2 + (x > 1 & x < 2) * 1 + (x > 2 &          x < 5) * -1 }
      #>  min lq    mean median uq   max neval cld
      #>   21 28 89.1662     31 67 67965 10000   b
      #>   21 28 75.9365     31 68  4953 10000  ab
      #>   21 28 73.5522     31 67  4509 10000  a

      <sup>Created on 2019-01-15 by the reprex package (v0.2.1)</sup>

        tctcab 要是 switch() 支持这种情况就好了。fun3 可真有意思。