首页 > 解决方案 > 使用 nlsLM 在函数内使用 combn 进行非线性回归

问题描述

给定的是数据框的几行DATA

> dput(DATA[c(1,7,20,25,26,53,89),])
structure(list(Lanes = c(3, 3, 3, 3, 3, 3, 3), N_b = c(5, 5, 
5, 5, 5, 5, 5), A = c(-12, -12, -15, -9, -9, -15, -9), x.sqr = 
c(1440, 1440, 2250, 810, 810, 2250, 810), e_1 = c(21.8, 21.8, 
29, 14.6, 14.6, 29, 14.6), e_2 = c(9.8, 9.8, 17, 2.6, 2.6, 17, 
2.6), e_3 = c(-2.2, -2.2, 5, -9.4, -9.4, 5, -9.4), e_4 = 
c(-14.2, -14.2, -7, 0, 0, -7, 0), e_5 = c(0, 0, -19, 0, 0, -19, 0), 
S = c(12, 12, 15, 9, 9, 15, 9), CSi = c(0.59189685884369, 
0.574916237257971, 0.644253184434141, 0.474070747691647, 
0.492033722080107, 0.644904371480046, 0.49900365977452), 
m = c(0.85, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85)), row.names = c(1L, 
7L, 20L, 25L, 26L, 53L, 89L), class = "data.frame")

我编写下面的函数用于非线性回归nlsLM

library(minpack.lm)

Prposed <- function(N_b,Lanes,m,A,x.sqr,e_1,e_2,e_3,e_4,e_5,S,a) {
  e <- data.frame(e_1,e_2,e_3,e_4,e_5)
  CSi <- m * ((Lanes/N_b) + (A * combn(e,Lanes,sum) / x.sqr) * (b*S^a))
  return(CSi)
}

nlsLM <- nlsLM(CSi ~ Prposed(N_b,Lanes,m,A,x.sqr,e_1,e_2,e_3,e_4,e_5,S,a,b), 
             data = DATA, 
             start = c(a = 0.01, b = 0.01))

summary(nlsLM)

我不断收到一个错误,它来自我如何e_1, e_2, etc..使用combn函数定义列。

更新

我发现了另一个问题:运行 nlsLM 时出错,但适用 于在原始函数中使用 for 循环的 nls,并且似乎nls2library(nls2). combn我想知道是否可以通过使用 for 循环来完全摆脱该术语。

标签: rfunctioncombinationsnon-linear-regressionnls

解决方案


这不是一个实际的答案,因为它在修复错误后会生成一个新错误,combn但这可能会给你一些方向。

我认为您正在尝试nlsLMDATA. 您需要在Prposed函数中分别传递每一行。另请注意,函数中需要aandb才能执行计算,因此它们需要作为函数的参数传递,我认为使用startin传递它们是nlsLM行不通的。

因此,将您的功能更改为:

library(minpack.lm)

Prposed <- function(N_b,Lanes,m,A,x.sqr,e_1,e_2,e_3,e_4,e_5,S,a, b) {
  e <- data.frame(e_1,e_2,e_3,e_4,e_5)
  CSi <- m * ((Lanes/N_b) + (A * combn(e,Lanes,sum) / x.sqr) * (b*S^a))
  return(CSi)
}

现在让我们为第一行运行这个DATA

x <- DATA[1, ]
Prposed(x[[2]], x[[1]], x[[12]], x[[3]], x[[4]], x[[5]], x[[6]], x[[7]], x[[8]],
        x[[9]],x[[10]],a = 0.01, b = 0.01)

#[1] 0.5078651 0.5087365 0.5077053 0.5096079 0.5085767 0.5094481 0.5104793 
#    0.5094481 0.5103195 0.5111909

我不知道理论,所以我不知道这些数字是否有意义/正确。但是,当您将其插入nlsLM功能时,它会给出错误。

nlsLM(CSi~Prposed(x[[2]],x[[1]],x[[12]], x[[3]],x[[4]],x[[5]],x[[6]],x[[7]],
    x[[8]], x[[9]],x[[10]],a = 0.01, b = 0.01),data = DATA)

getInitial.default(func, data, mCall = as.list(match.call(func, : no 'getInitial' method found for "function" objects

这是因为nlsLM期望一个formula对象但我们传递给它的是值吗?我不知道。


完成上述步骤后,您可以将其插入apply并运行为:

apply(DATA, 1, function(x) {
  nlsLM(CSi~Prposed(x[[2]],x[[1]],x[[12]], x[[3]],x[[4]],x[[5]],x[[6]],x[[7]],
    x[[8]], x[[9]],x[[10]],a = 0.01, b = 0.01), data = DATA)
})

它可以工作并生成没有nlsLM功能的数字:

apply(DATA, 1, function(x) {
  Prposed(x[[2]],x[[1]],x[[12]], x[[3]],x[[4]],x[[5]],x[[6]],x[[7]],x[[8]], 
         x[[9]],x[[10]],a = 0.01, b = 0.01) 
})

#              1         7        20        25        26        53        89
# [1,] 0.5078651 0.5078651 0.5070307 0.5092470 0.5092470 0.5070307 0.5092470
# [2,] 0.5087365 0.5087365 0.5077293 0.5083395 0.5083395 0.5077293 0.5083395
# [3,] 0.5077053 0.5077053 0.5084280 0.5083395 0.5083395 0.5084280 0.5083395
# [4,] 0.5096079 0.5096079 0.5084280 0.5094980 0.5094980 0.5084280 0.5094980
# [5,] 0.5085767 0.5085767 0.5091267 0.5094980 0.5094980 0.5091267 0.5094980
# [6,] 0.5094481 0.5094481 0.5098253 0.5085905 0.5085905 0.5098253 0.5085905
# [7,] 0.5104793 0.5104793 0.5091267 0.5106565 0.5106565 0.5091267 0.5106565
# [8,] 0.5094481 0.5094481 0.5098253 0.5106565 0.5106565 0.5098253 0.5106565
# [9,] 0.5103195 0.5103195 0.5105240 0.5097490 0.5097490 0.5105240 0.5097490
#[10,] 0.5111909 0.5111909 0.5112227 0.5109075 0.5109075 0.5112227 0.5109075

推荐阅读