nls selfStart 函数的范围
Scope of nls selfStart functions
我正在构建一个包,它将:
- 读入一个数据集
- 确定对数据建模需要哪些组件1
- 使用这些组件构建自启动 NLS 模型
- 将该模型应用于数据
结果存储在包含数据、模型和 nls 结果的列表中。一切正常,直到第 4 步。我已将构建的模型存储在列表中,R 不再将它们识别为 selfStart 函数。
这是一个说明我的问题的玩具示例。以下函数(来自 SSlogis
手册)在顶层运行良好:
Chick.1 <- ChickWeight[ChickWeight$Chick == 1, ]
fm1 <- nls(weight ~ SSlogis(Time, Asym, xmid, scal), data = Chick.1)
fm1
Nonlinear regression model
model: weight ~ SSlogis(Time, Asym, xmid, scal)
data: Chick.1
Asym xmid scal
937.02 35.22 11.41
residual sum-of-squares: 76.66
Number of iterations to convergence: 0
Achieved convergence tolerance: 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)
Error in getInitial.default(func, data, mCall = as.list(match.call(func, :
no 'getInitial' method found for "function" objects
我的工作流程最终将包括处理数十个数据集,因此我想将每个数据集及其关联模型保存在其自己的对象中(这些对象可能最终会出现在对象列表中)。有什么方法可以维护或恢复我的 selfStart 函数的环境,即使它们存储在另一个列表中也是如此?
更新
为了响应 Gregor 的建议,我尝试了这个:
nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)",
"myobj$model")), data = myobj$data)
Error in nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)", :
singular gradient
In addition: Warning message:
In nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)", :
No starting values specified for some parameters.
Initializing ‘Asym’, ‘xmid’, ‘scal’ to '1.'.
Consider specifying 'start' or using a selfStart model
更新 2
受@Gregor 的启发,我想出了一个解决方法:
nlsDispatch <- function(obj){
GLOBAL_NLS <<- obj$model
nls(weight ~ GLOBAL_NLS(Time, Asym, xmid, scal), data = myobj$data)
}
nlsDispatch(myobj)
Nonlinear regression model
model: weight ~ GLOBAL_NLS(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
这行得通,但是将我的函数放到全局环境中很难看。它表明,如果我能更好地处理环境,我应该能够避免滥用全局环境来完成这项工作。
1:在我的应用程序中,这主要是计算峰值的问题,并计算出需要多少条正态曲线为他们建模。
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
完成时,搜索列表中将附加两个项目(而在先前的方法中,它总是覆盖全局变量,这样就不会发生)所以我们检查搜索路径上是否没有这样的列表,如果有则停止并报错。
我正在构建一个包,它将:
- 读入一个数据集
- 确定对数据建模需要哪些组件1
- 使用这些组件构建自启动 NLS 模型
- 将该模型应用于数据
结果存储在包含数据、模型和 nls 结果的列表中。一切正常,直到第 4 步。我已将构建的模型存储在列表中,R 不再将它们识别为 selfStart 函数。
这是一个说明我的问题的玩具示例。以下函数(来自 SSlogis
手册)在顶层运行良好:
Chick.1 <- ChickWeight[ChickWeight$Chick == 1, ]
fm1 <- nls(weight ~ SSlogis(Time, Asym, xmid, scal), data = Chick.1)
fm1
Nonlinear regression model
model: weight ~ SSlogis(Time, Asym, xmid, scal) data: Chick.1
Asym xmid scal
937.02 35.22 11.41
residual sum-of-squares: 76.66Number of iterations to convergence: 0
Achieved convergence tolerance: 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)
Error in getInitial.default(func, data, mCall = as.list(match.call(func, :
no 'getInitial' method found for "function" objects
我的工作流程最终将包括处理数十个数据集,因此我想将每个数据集及其关联模型保存在其自己的对象中(这些对象可能最终会出现在对象列表中)。有什么方法可以维护或恢复我的 selfStart 函数的环境,即使它们存储在另一个列表中也是如此?
更新
为了响应 Gregor 的建议,我尝试了这个:
nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)",
"myobj$model")), data = myobj$data)
Error in nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)", :
singular gradient In addition: Warning message:
In nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)", :
No starting values specified for some parameters.
Initializing ‘Asym’, ‘xmid’, ‘scal’ to '1.'.
Consider specifying 'start' or using a selfStart model
更新 2
受@Gregor 的启发,我想出了一个解决方法:
nlsDispatch <- function(obj){
GLOBAL_NLS <<- obj$model
nls(weight ~ GLOBAL_NLS(Time, Asym, xmid, scal), data = myobj$data)
}
nlsDispatch(myobj)
Nonlinear regression model
model: weight ~ GLOBAL_NLS(Time, Asym, xmid, scal)
data: myobj$data
Asym xmid scal
937.02 35.22 11.41
residual sum-of-squares: 76.66Number of iterations to convergence: 0
Achieved convergence tolerance: 6.621e-07
这行得通,但是将我的函数放到全局环境中很难看。它表明,如果我能更好地处理环境,我应该能够避免滥用全局环境来完成这项工作。
1:在我的应用程序中,这主要是计算峰值的问题,并计算出需要多少条正态曲线为他们建模。
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
完成时,搜索列表中将附加两个项目(而在先前的方法中,它总是覆盖全局变量,这样就不会发生)所以我们检查搜索路径上是否没有这样的列表,如果有则停止并报错。