首页 > 解决方案 > 如何在长数据帧的数据子集中应用非线性回归?

问题描述

我有一个数据框,其中包含来自不同实验的多个结果。我想将每个实验的数据分别拟合到一个特定的函数,但是,我的 R 知识很浅。有什么帮助吗?

在下面的 MWE 中,参数的起始值是针对ex1数据的

ex <- c(rep("ex1", times=4), rep("ex2", times=4))
x <- rep(c(0,60,120,240), times = 2)
y <- c(0,3.73,3.08,4.07,0,1.4,2.6,2.6)

df <- data.frame(ex, x, y)

m <- nls(formula = y ~ ((a^2)*b*x)/(1+(a*b*x)),
         data = df,
         start = list(a=4.071, b=0.0253))

起始值:

对于 ex1: a = 4.071,b = 0.0253

对于 ex2: a = 2.584,b = 0.0155

标签: rdataframesubsetnon-linear-regressionnls

解决方案


1) 一个 nls 使用分组它可以在一个 nls 调用中完成,如下所示:

fo <- y ~ ((a[ex]^2)*b[ex]*x)/(1+(a[ex]*b[ex]*x))
st <- list(a = c(4.071, 2.504), b = c(0.0253, 0.0155))

m <- nls(fo, df, start = st)
m

给予:

Nonlinear regression model
  model: y ~ ((a[ex]^2) * b[ex] * x)/(1 + (a[ex] * b[ex] * x))
   data: df
     a1      a2      b1      b2 
3.76849 3.58989 0.06521 0.00385 
 residual sum-of-squares: 0.6989

Number of iterations to convergence: 8 
Achieved convergence tolerance: 4.731e-06

2)映射或者我们可以遍历对每个组执行单独的 nls 的组。st是从上面。

fo1 <- y ~ ((a^2)*b*x)/(1+(a*b*x))
st1 <- split(as.data.frame(st), levels(df$ex))

L <- Map(nls, data = split(df, df$ex), st1, MoreArgs = list(formula = fo1))
L

给出这个nls对象列表:

$ex1
Nonlinear regression model
  model: y ~ ((a^2) * b * x)/(1 + (a * b * x))
   data: dots[[1L]][[2L]]
      a       b 
3.76848 0.06521 
 residual sum-of-squares: 0.4922

Number of iterations to convergence: 7 
Achieved convergence tolerance: 3.774e-06

$ex2
Nonlinear regression model
  model: y ~ ((a^2) * b * x)/(1 + (a * b * x))
   data: dots[[1L]][[2L]]
      a       b 
3.58989 0.00385 
 residual sum-of-squares: 0.2067

Number of iterations to convergence: 9 
Achieved convergence tolerance: 3.302e-06

3)更新第三种方法是首先运行组合的nls,然后为每个组设置子集。 fo1并且st是从上面。

m2 <- nls(fo1, df, start = sapply(st, mean))
lvs <- levels(df$ex)
L2 <- lapply(lvs, function(lv) do.call("update", list(m2, subset = df$ex == lv)))

它还提供了一个nls对象列表。

4) nlsList 另一种方法是使用nlme包中的nlsList。st是从上面。

library(nlme)

fo2 <- y ~ ((a^2) * b * x)/(1 + (a * b * x)) | ex
m3 <- nlsList(fo2, df, start = sapply(st, mean))
m3

给出以下nlsList对象:

Call:
  Model: y ~ ((a^2) * b * x)/(1 + (a * b * x)) | ex 
   Data: df 

Coefficients:
           a           b
ex1 3.768487 0.065212898
ex2 3.589892 0.003850294

Degrees of freedom: 8 total; 4 residual
Residual standard error: 0.4179985

残差平方和

对于 (1),残差平方和为

tapply(resid(m)^2, df$ex, sum)

对于 (2) 它是:

sapply(L, deviance)

并且对于 (3) 和 (4) 与 L2 或 m3 代替 L 相同。


推荐阅读