R:由非线性拟合函数生成的函数 - 如何指定参数集

时间:2015-08-30 09:44:28

标签: r function nls function-declaration

我要做的是使用我的完整模型的可能子模型进行非线性回归,然后使用AIC标准选择最合适的模型。问题是生成所有可能的子模型,然后将它们应用于nls函数以找到最合适的。

我们说我有一个数据:

x <- rnorm(100)
y <- 1+x+x^2-x^3-x^4+rnorm(100, sd=0.1)

完整公式作为变量x和一些参数abcde的函数:

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参数)。

但是当我没有为bd指定起始值时(我应该能够这样做,因为我在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)
}

但它不起作用,我不知道如何正确实施它。

1 个答案:

答案 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)