【问题标题】:How to define a piecewise function in R如何在 R 中定义分段函数
【发布时间】:2012-01-09 11:56:04
【问题描述】:

我想用 R 定义一个分段函数,但是我的 R 代码出错了。欢迎提出任何建议。

x<-seq(-5, 5, by=0.01)
  for (x in -5:5){
  if (-0.326 < x < 0.652) fx<- 0.632
  else if (-1.793<x<-1.304) fx<- 0.454  
  else if (1.630<x<2.119) fx<-0.227  
  else fx<- 0 }

【问题讨论】:

  • 可能需要澄清一下,这个例子是一个阶跃函数,一个特殊的分段函数类。对于阶跃函数,stepfun(@KenWIlliams 提到)和approxfun 都可以很好地工作。 approxfun 也适用于分段线性函数(但不是一般的分段函数)。

标签: r function piecewise


【解决方案1】:

试试这个:

x <- seq(-5, 5, 0.01)
fx <- (x > -0.326 & x <0.625) * 0.632 +
      (x > -1.793 & x < -1.304) * 0.454 +
      (x > 1.630 & x < 2.119) * 0.227
plot(x, fx)

【讨论】:

  • 不错。鉴于 Gabor 的经验,我敢打赌这比我的“切换”方法运行得更快(对于大量“细分”)。
【解决方案2】:

我参加聚会有点晚了,但我忍不住发布了更多方法来做到这一点。两者都利用 R 功能在实线上处理间隔。

如果您在向量cutsvals 中定义切点和函数值,如下所示:

cuts <- c( -Inf, -1.793, -1.304, -0.326, 0.625, 1.630, 2.119 )
vals <- c(    0,  0.454,      0,  0.632,     0, 0.227,     0 )

然后您可以使用findInterval 在您的切点中有效地查找x 的值:

fx <- vals[findInterval(x, c(-Inf, cuts))]

如果这个函数需要做一些比查找常量值更有趣的事情,你可以在vals 中放入表达式或函数或任何你想要的东西,如果你愿意,也可以使用list

或者,由于这个函数是一个阶梯函数,你可以使用stepfun

f <- stepfun(cuts[-1], vals)
fx <- f(x)

那么你也可以使用stepfun 的漂亮绘图方法了。

【讨论】:

    【解决方案3】:

    或者你可以使用ifelse

    fx <- ifelse(x > -0.326 & x <0.625, 0.632,
       ifelse(x > -1.793 & x < -1.304,  0.454,
       ifelse(x > 1.630 & x < 2.119, 0.227, 0)))
    

    【讨论】:

      【解决方案4】:

      也许如果你把条件分开

      if((-1.793<x) & (x < 0.652)) ...
      

      编辑:这似乎还不是全部,这是一种不同的方法:

      x<-seq(-5, 5, by=0.01)
      fx <- function(x) {
          res <- rep(0, length(x))
          res[(-0.326 < x) & (x < 0.652)] <- 0.632
          res[(-1.793<x) & (x < (-1.304))] <- 0.454  
          res[(1.630<x) & (x <2.119)] <- 0.227  
          return(res)
      }
      fx(x)
      

      【讨论】:

      • 感谢您的回答。我会试一试的。
      • 小心那些按位的&amp;。在这种情况下没问题,但最好坚持使用&amp;&amp;,同样使用|| 而不是|
      • @fotNelton:这是 R,不是 c++ :-)。 &amp;&amp;&amp; 之间有区别,但两者都不是按位运算符。
      • 谢谢,很高兴知道!我想我得再查一遍。编辑:啊,我明白了。一个是矢量化的,而另一个不是。
      【解决方案5】:

      还有一个选项,这次使用cut

      regions <- c(-Inf, -1.793, -1.304, -0.326, 0.652, 1.63, 2.119, Inf)
      group <- cut(x, regions)
      f_values <- c(0, 0.454, 0, 0.632, 0, 0.227, 0)
      (fx <- f_values[group])
      

      【讨论】:

        【解决方案6】:

        除非您有不同的截止点,否则我会使用 switch 。这是一个带有简化切割值的示例。

        xcuts<-1:10 #the values at which you change fx assignment
        xx<- seq(1.5,10,5, by =10) #vector of fx values to be selected
        switch(max(which(x>xcuts)), 
        1= fx<-xx[1], 
        2= fx<-xx[2], 
        ..."et cetera"... 
        ) 
        

        在 x 上循环。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-04
          • 1970-01-01
          • 2021-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多