我要做的是使用我的完整模型的可能子模型进行非线性回归,然后使用AIC标准选择最合适的模型。问题是生成所有可能的子模型,然后将它们应用于nls
函数以找到最合适的。
我们说我有一个数据:
x <- rnorm(100)
y <- 1+x+x^2-x^3-x^4+rnorm(100, sd=0.1)
完整公式作为变量x
和一些参数a
,b
,c
,d
,e
的函数:
full <- function(x, a, b, c, d, e){
return(a + b*x + c*x^2 + d*x^3 + e*x^4)
}
(我知道这是非线性模型的一个愚蠢的例子,我可以使用数据转换+线性模型,但我希望它很简单)
我想生成所有可能的子模型,跳过一些参数。 我试图将那些跳过的参数设置为零:
skip <- function(args){
# args = subset of c("a", "b", "c", "d", "e")
return (function(x, a=0, b=0, c=0, d=0, e=0) {
par <- c("a", "b", "c", "d", "e")
parameters <- lapply(par, function(p){
if(p %in% args){
return (0)
}
else{
return (get(p))
}
})
names(parameters) <- c("a", "b", "c", "d", "e")
return (with(parameters, a + b*x + c*x^2 + d*x^3 + e*x^4))
})
}
我写了一个函数来将这些公式应用到nls
:
apply_nls <- function(func, start){
fit <- nls(y~func(x, a, b, c, d, e),
start=start)
return(fit)
}
问题在于它不起作用。如果我确定了ommited参数的起始值:
apply_nls(skip("e"), start=list(a=1, b=1, c=1, d=-1, e=-1))
然后我收到错误消息
初始参数估计时的奇异梯度矩阵
(因为我的功能确实不依赖于e
参数)。
但是当我没有为b
和d
指定起始值时(我应该能够这样做,因为我在skip
中指定了这些参数的默认值): / p>
apply_nls(skip("e"), start=list(a=1, b=1, c=1, d=-1))
然后我收到另一条错误消息:
在数据&#39;:e
中没有起始值的参数
我想我应该限制skip
和/或apply_nls
函数中的参数,这样它们只需要当时需要的参数,例如:
apply_nls <- function(func, args, start){
fit <- nls(y~func(x, args),
start=start)
return(fit)
}
但它不起作用,我不知道如何正确实施它。
答案 0 :(得分:1)
如果有人有兴趣,我已经解决了这个问题。
函数apply_nls
在表单中起作用:
apply_nls <- function(func, par, start){
fit <- nls(y~do.call(func, args=append(list(x=x), mget(par))),
start=start)
return(fit)
}
此处mget
返回给定参数名称(作为字符串)的每个参数的值,do.call
允许使用结果参数提供func
。
跳过某些参数后,此func
是一个函数(子公式),par
是剩余参数,start
是这些参数的起始值。因此apply_nls
的应用如下所示:
apply_nls(skip("e"), par=c("a", "b", "c", "d"), start=list(a=1, b=1, c=1, d=-1))
为了获得子模型的所有适合度:
1)我为所有这些分配参数名称和起始值
parameters <- c("a", "b", "c", "d", "e")
start <- list(a=1, b=1, c=1, d=-1, e=-1)
2)我列出了所有丢弃参数的组合
drops <- append(NA, c(parameters,
combn(parameters, 2, simplify=F),
combn(parameters, 3, simplify=F),
combn(parameters, 4, simplify=F)))
3)我写了两个函数,它们会返回剩余的参数或给定要删除的参数的起始值:
choose_starts <- function(args, start){
return(start[!(names(start) %in% args)])
}
choose_pars <- function(args, all_pars){
return(all_pars[!all_pars %in% args])
}
4)在给定跳过的参数的情况下,我创建公式,参数和起始值的所有组合:
all_formulas <- lapply(drops, skip)
all_starts <- lapply(drops, choose_starts, start)
all_pars <- lapply(drops, choose_pars, parameters)
5)我适合所有上述的非线性模型。
all_fits <- mapply(apply_nls, all_formulas, all_pars, all_starts, SIMPLIFY=F)