Ошибка, включающая структуру корреляции в функции с gamm

#r #function #nlme #mgcv

#r #функция #nlme #mgcv

Вопрос:

Я пытаюсь создать свою собственную функцию, которая содержит 1.) функцию mgcv gamm и 2.) вложенный аргумент автокорреляции (ARMA). Я получаю сообщение об ошибке, когда пытаюсь запустить функцию следующим образом:

 df <- AirPassengers
df <- as.data.frame(df)
df$month <- rep(1:12)
df$yr <- rep(1949:1960,each=12)
df$datediff <- 1:nrow(df)

try_fxn1 <- function(dfz, colz){gamm(dfz[[colz]] ~ s(month, bs="cc",k=12) s(datediff,bs="ts",k=20), data=dfz,correlation = corARMA(form = ~ 1|yr, p=2))}

try_fxn1(df,"x")
 

Ошибка в eval (predvars, data, env): объект ‘dfz’ не найден

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

 try_fxn2 <- function(dfz, colz){gamm(dfz[[colz]] ~ s(month, bs="cc",k=12)  s(datediff,bs="ts",k=20), data=dfz)}

try_fxn2(df,"x")
 

Любые идеи о том, как я могу изменить try_fxn1, чтобы функция вела себя так, как ожидалось? Спасибо!

Ответ №1:

Вы путаете вектор с символическим представлением этого вектора при построении формулы.

Вы не хотите dfz[[colz]] , чтобы в качестве ответа в формуле, вы хотите x или что бы вы ни установили colz . То, что вы получаете, это

 dfz[[colz]] ~ ...
 

когда то, что вы действительно хотите, это переменная colz :

 colz ~ ...
 

И вам не нужен литерал colz , но все, что colz оценивается. Для этого вы можете создать формулу, вставив части вместе:

 fml <- paste(colz, '~ s(month, bs="cc", k=12)   s(datediff,bs="ts",k=20)')
 

Это превращается colz в то, что оно хранило, а не в литерал colz :

 > fml
[1] "x ~ s(month, bs="cc", k=12)   s(datediff,bs="ts",k=20)"
 

Затем преобразуйте строку в объект формулы, используя formula() или as.formula() .

Тогда окончательное решение:

 fit_fun <- function(dfz, colz) {
    fml <- paste(colz, '~ s(month, bs="cc", k=12)   s(datediff,bs="ts",k=20)')
    fml <- formula(fml)
    gamm(fml, data = df, correlation = corARMA(form = ~ 1|yr, p=2))
}
 

Это действительно не проблема с corARMA() part, кроме того, что запускает несколько иной код вычисления для формулы. Руководящая мантра здесь заключается в том, чтобы всегда получать формулу так, как вы бы ее вводили, если бы не программировали с помощью формул. Вы бы никогда (или никогда не должны) писать формулу типа

 gamm(df[[var]] ~ x   s(z), ....)
 

Хотя это может сработать в некоторых настройках, оно с треском провалится, если вы когда-нибудь захотите использовать predict()`, и оно терпит неудачу, когда вам нужно сделать что-то более сложное.