Как передать результаты цикла в качестве начальных параметров для модели nlslm?

#r #for-loop #nls

#r #для цикла #nls

Вопрос:

Я запускаю модель нелинейной регрессии, для запуска которой требуются начальные значения, но количество переменных, которые я хочу включить, может быть слишком большим, чтобы вручную вводить все значения — поэтому мне было интересно, есть ли альтернатива этому.

 set.seed(12345)
y = rnorm(100, 1000,150)
x1 = rnorm(100,10000,251)
x2 = rnorm(100, 3000,654)
x3 = rnorm(100, 25000,100)
x4 = rnorm(100, 200000,589)
x5 = rnorm(100, 31657,296)

adstock <- function(x,rate=0){
  return(as.numeric(stats::filter(x=log(x 1),filter=rate,method="recursive")))
}

library(minpack.lm)

nlsLM(y~b0  
        b1 * adstock(x1, r1)
        b2 * adstock(x2, r2)
        b3 * adstock(x3, r3)
        b4 * adstock(x4, r4)
        b5 * adstock(x5, r5)
      
      , algorithm = "LM"

# this is where I need to paste the results from the loop 
      , start = c(b0=1,b1=1,b2=1,b3=1,b4=1,b5=1
                  ,r1=0.1,r2=0.1,r3=0.1,r4=0.1,r5=0.1
                  )
# end
      
      , control = list(maxiter = 200)
)
 

Моя идея заключалась в том, чтобы использовать цикл для передачи значений в модель, но я не могу заставить его работать (следующий код должен быть для коэффициентов b_i)

 test_start <- NULL

for(i in 1:(5 1)) {
  test_start[i] = paste0("b",i-1,"=",1)
}

cat(test_start)
 

Это результат, который не совсем соответствует ожиданиям модели:

b0 = 1 b1 = 1 b2 = 1 b3 = 1 b4 = 1 b5 = 1

Как я могу передать результаты цикла в модель? Кроме того, как я могу добавить начальные коэффициенты r_i к начальным коэффициентам b_i в цикле? Любая помощь была бы очень признательна.

PS: на данный момент мне интересно присвоить каждому b0, b1, …, b5 одинаковое значение (в данном случае 1) и каждому r1, r2, …, r5 одинаковое значение (в данном случае 0,1)

Ответ №1:

Определите данные как DF и формулу как fo , а затем выделите b r переменные и. Определяющая линия v создает вектор с их именами, а линия, определяющая st именованный вектор со значением 1 для b ‘s и 0.1 для r ‘s.

 DF <- data.frame(y, x1, x2, x3, x4, x5)

n <- ncol(DF) - 1
rhs <- c("b0", sprintf("b%d * adstock(x%d, r%d)", 1:n, 1:n, 1:n))
fo <- reformulate(rhs, "y")

v <- grep("[br]", all.vars(fo), value = TRUE)
st <- setNames(grepl("b", v)   0.1 * grepl("r", v), v)
st

nlsLM(fo, DF, start = st, algorithm = "LM", control = list(maxiter = 200))
 

Что касается комментария, попробуйте определить rhs так. В первой строке возьмите любое подмножество labs , которое вы хотите, например labs <- labels(...)[1:9] , или измените формулу в первой строке, например labs <- labels(terms(y ~ .*(1 x1), data = DF))

 labs <- labels(terms(y ~ .^2, data = DF))
labs <- sub(":", "*", labs)
n <- length(labs)
rhs <- c("b0", sprintf("b%d * adstock(%s, r%d)", 1:n, labs, 1:n))
 

Комментарии:

1. отличная точка зрения! но теперь у меня есть дополнительный вопрос: поскольку я больше не могу вводить формулу (из-за объекта «fo»), каков наилучший способ добавления взаимодействий [например: …. b6 * adstock(x1 * x2, r6) b7 * adstock (x1 * x3,r7) etc …] ? должен ли я создать переменную x6 в DF, содержащую x1 * x2? или у вас есть другие предложения? Меня могут заинтересовать некоторые конкретные взаимодействия, а не все возможные..

2. См. раздел Добавленная часть.

3. да, изменение объекта «labs» определенно сработает для меня! большое спасибо за вашу помощь!