nls selfStart函数的范围

时间:2016-04-13 21:51:50

标签: r nls

我正在构建一个包:

  1. 读入数据集
  2. 确定建模数据 1
  3. 所需的组件
  4. 使用这些组件构建自启动NLS模型
  5. 将该模型应用于数据
  6. 结果存储在包含数据,模型和nls结果的列表中。一切正常,直到第4步。我已将构建的模型存储在列表中,R不再将它们识别为selfStart函数。

    这是一个说明我问题的玩具示例。以下功能(来自SSlogis手册)在顶层工作正常:

     Chick.1 <- ChickWeight[ChickWeight$Chick == 1, ]
     fm1 <- nls(weight ~ SSlogis(Time, Asym, xmid, scal), data = Chick.1)
     fm1
    
      

    非线性回归模型
        型号:重量~SSlogis(时间,Asym,xmid,scal)      数据:小鸡.1     Asym xmid scal
      937.02 35.22 11.41
       残差平方和:76.66

         

    收敛的迭代次数:0
      实现收敛容差:7.778e-07

    但是当我将函数和数据存储在一个列表中时,R不再将自启动功能视为自启动:

    myobj <- list()
    myobj$model <- SSlogis
    myobj$data <- ChickWeight[ChickWeight$Chick == 1, ]
    
    nls(weight ~ myobj$model(Time, Asym, xmid, scal), data = myobj$data)
    
      

    getInitial.default出错(func,data,mCall = as.list(match.call(func,:
    )     找不到“函数”对象的“getInitial”方法

    我的工作流程最终将包括处理数十个数据集,因此我希望将每个数据集及其相关模型保存在自己的对象中(这些对象可能最终会出现在对象列表中)。有没有办法维护或恢复我的selfStart函数的环境,即使它们存储在另一个列表中?

    更新

    为了回应格雷戈尔的建议,我尝试了这个:

    nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)",
                           "myobj$model")), data = myobj$data)
    
      

    nls中的错误(as.formula(sprintf(“weight~%s(Time,Asym,xmid,scal)”,:
        奇异梯度   另外:警告信息:
      在nls中(as.formula(sprintf(“weight~%s(Time,Asym,xmid,scal)”,:
        没有为某些参数指定起始值   将'Asym','xmid','scal'初始化为'1'   考虑指定'start'或使用selfStart模型

    更新2

    受到@Gregor的启发,我想出了一个解决方法:

    nlsDispatch <- function(obj){
      GLOBAL_NLS <<- obj$model
      nls(weight ~ GLOBAL_NLS(Time, Asym, xmid, scal), data = myobj$data) 
    }
    
    nlsDispatch(myobj)
    
      

    非线性回归模型
        型号:重量~GLOBAL_NLS(时间,Asym,xmid,scal)
         数据:myobj $ data
        Asym xmid scal
      937.02 35.22 11.41
       残差平方和:76.66

         

    收敛的迭代次数:0
      实现收敛容差:6.621e-07

    这很有效,但将我的功能放到全球环境中是很难看的。它表明如果我能更好地处理环境,我应该能够避免滥用全球环境来完成这项工作。

    1 :在我的应用程序中,主要是计算峰值,并确定需要多少条Normal曲线来建模它们。

1 个答案:

答案 0 :(得分:2)

1)这有效:

Model <- myobj$model
nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data)

Nonlinear regression model
  model: weight ~ Model(Time, Asym, xmid, scal)
   data: myobj$data
  Asym   xmid   scal 
937.02  35.22  11.41 
 residual sum-of-squares: 76.66

Number of iterations to convergence: 0 
Achieved convergence tolerance: 6.621e-07

2)对于自启动功能来说似乎确实存在范围。问题出现在使用此行的getInitial.formula中:

func <- get(as.character(object[[2L]][[1L]]))

请注意,get(环境)没有第二个参数,因此它不会关注环境。

因此,如果您想将上述解决方案放在一个函数中,那么您将需要像这样解决它:

f <- function() {
  myobj <- list()
  myobj$model <- SSlogis
  myobj$data <- ChickWeight[ChickWeight$Chick == 1, ]
  Model <<- myobj$model
  nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data)
}
f()

3)另一个工作是附加模型。这将使其远离全球工作空间。请注意,我们之后将其分离,因此该功能不会留下任何痕迹。

f2 <- function() {
  on.exit(detach())
  if (any(grepl("list", search()))) stop("list already on search path")
  myobj <- list()
  myobj$model <- SSlogis
  myobj$data <- ChickWeight[ChickWeight$Chick == 1, ]
  attach(list(Model = myobj$model))
  nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data)
}
f2()

请注意,如果detach没有出现,则下次attach完成时,搜索列表中会附加两个项目(而在之前的方法中,它总是覆盖全局变量,所以这是不可能发生的)所以我们检查搜索路径上没有这样的列表,如果存在错误则停止。