问题描述
我正在尝试创建自己的函数,其中包含 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,k=12)+ s(datediff,data=dfz)}
try_fxn2(df,"x")
关于如何修改 try_fxn1 以使函数按预期运行的任何想法?谢谢!
解决方法
在构建公式时,您将向量与该向量的符号表示混淆了。
您不希望 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\",bs=\"ts\",k=20)"
然后使用 formula()
或 as.formula()
将字符串转换为公式对象。
最后的解决方案是:
fit_fun <- function(dfz,colz) {
fml <- paste(colz,k=20)')
fml <- formula(fml)
gamm(fml,data = df,correlation = corARMA(form = ~ 1|yr,p=2))
}
这真的不是 corARMA()
部分的问题,除了会触发公式的一些不同的评估代码。这里的指导原则是总是得到一个公式,就像你在不使用公式编程的情况下输入它一样。你永远不会(或不应该)写出像
gamm(df[[var]] ~ x + s(z),....)
虽然这在某些设置中可能有效,但如果您想使用 predict()` 它将失败,而当您必须做一些更复杂的事情时它会失败。