【问题标题】:Errors in segmented package: breakpoints confusion分段包中的错误:断点混淆
【发布时间】:2012-08-21 13:15:48
【问题描述】:

使用分段包创建分段线性回归我在尝试设置自己的断点时看到错误;似乎只有当我尝试设置两个以上时。

(编辑)这是我正在使用的代码:

# data
bullard <- structure(list(Rt = c(0, 4.0054, 25.1858, 27.9998, 35.7259, 39.0769, 
45.1805, 45.6717, 48.3419, 51.5661, 64.1578, 66.828, 111.1613, 
114.2518, 121.8681, 146.0591, 148.8134, 164.6219, 176.522, 177.9578, 
180.8773, 187.1846, 210.5131, 211.483, 230.2598, 262.3549, 266.2318, 
303.3181, 329.4067, 335.0262, 337.8323, 343.1142, 352.2322, 367.8386, 
380.09, 388.5412, 390.4162, 395.6409), Tem = c(15.248, 15.4523, 
16.0761, 16.2013, 16.5914, 16.8777, 17.3545, 17.3877, 17.5307, 
17.7079, 18.4177, 18.575, 19.8261, 19.9731, 20.4074, 21.2622, 
21.4117, 22.1776, 23.4835, 23.6738, 23.9973, 24.4976, 25.7585, 
26.0231, 28.5495, 30.8602, 31.3067, 37.3183, 39.2858, 39.4731, 
39.6756, 39.9271, 40.6634, 42.3641, 43.9158, 44.1891, 44.3563, 
44.5837)), .Names = c("Rt", "Tem"), class = "data.frame", row.names = c(NA, 
-38L))

library(segmented)

# create a linear model
out.lm <- lm(Tem ~ Rt, data=bullard)

o<-segmented(out.lm, seg.Z=~Rt, psi=list(Rt=c(200,300)), control=seg.control(display=FALSE))

使用psi 选项,我尝试了以下方法:

psi = list(x = c(150, 300)) -- OK
psi = list(x = c(100, 200)) -- OK
psi = list(x = c(200, 300)) -- OK
psi = list(x = c(100, 300)) -- OK
psi = list(x = c(120, 150, 300)) -- error 1 below
psi = list(x = c(120, 300)) -- OK
psi = list(x = c(120, 150)) -- OK
psi = list(x = c(150, 300)) -- OK
psi = list(x = c(100, 200, 300)) -- error 2 below

(1)Error in segmented.lm(out.lm, seg.Z = ~Rt, psi = list(Rt = c(120, 150, : only 1 datum in an interval: breakpoint(s) at the boundary or too close

(2)Error in diag(Cov[id, id]) : subscript out of bounds

我已经列出了我的数据at this question,但作为指导,x 数据的限制约为 0--400。

与此相关的第二个问题是:我如何使用这个分段包实际修复断点?

【问题讨论】:

  • 数据可能在另一个问题中,但你能把它变成一个可重现的例子,准确地显示你一直在尝试的函数调用吗?
  • 如果您使用seg.lm.fit PSI 的文档,请说“适当的矩阵,包括要估计的断点的起始值”
  • 嗨,肖恩,感谢您的回复。我添加了我的代码,虽然我不确定如何轻松地将我的数据转换为脚本(可以说是内联),所以我离开了 read.delim 调用。
  • 也许您可以添加 dput(head(bullard)) 的输出来了解数据的样子。
  • @seancarmody 啊,真可爱。谢谢,不知道怎么弄。数据集足够小,可以将所有内容都包含在内。

标签: r linear-regression


【解决方案1】:

这里的问题似乎是segmented 包中的错误捕获很差。查看segmented.lm 的代码可以进行一些调试。例如psi = list(x = c(100, 200, 300))的情况下,拟合的增广线性模型如下所示:

lm(formula = Tem ~ Rt + U1.Rt + U2.Rt + U3.Rt + psi1.Rt + psi2.Rt + 
    psi3.Rt, data = mf)

Call:
lm(formula = Tem ~ Rt + U1.Rt + U2.Rt + U3.Rt + psi1.Rt + psi2.Rt + 
    psi3.Rt, data = mf)

Coefficients:
(Intercept)           Rt        U1.Rt        U2.Rt        U3.Rt      psi1.Rt        
   15.34303      0.04149      0.04591    742.74186   -742.74499      1.02252       
   psi2.Rt      psi3.Rt  
        NA           NA  

如您所见,拟合具有NA 值,然后导致退化的方差-协方差矩阵(在代码中称为Cov)。该函数不检查这一点,并尝试从Cov 中提取对角线条目,并失败并显示错误消息。至少第一个错误,虽然可能不是很有帮助,但被函数本身捕获并表明断点太近了。

在函数中没有更好的错误捕获的情况下,我认为您所能做的就是采用试错法(并避免断点太近)。例如,psi = list(x = c(50, 200, 300)) 似乎可以正常工作。

【讨论】:

  • 当你准确地知道你的断点时,这个错误真的很令人沮丧。
  • 五年前的错误似乎仍然存在。有趣的是:当我重复我的segmented() 电话时,错误有时会消失!
【解决方案2】:

如果您使用whiletryCatch,您可以重复执行该命令,直到它确定模型@jaySf 中没有错误。我猜这取决于函数中的随机化器设置,可以在seg.control 中看到。

lm.model <- lm(xdat ~ ydat, data = x)
if.false <- F
while(if.false == F){
  tryCatch({
    s <- segmented(lm.model, seg.Z =~ydata, psi = NA)
    if.false <- T
  }, error = function(e){
  }, finally = {})
}

【讨论】:

  • 有这样永远的风险,有什么办法只尝试一百次然后放弃?
  • 可以添加循环索引,如:lm.model
猜你喜欢
  • 2016-05-08
  • 2021-09-17
  • 2020-06-10
  • 1970-01-01
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
  • 1970-01-01
相关资源
最近更新 更多