包含 gamm 函数相关结构的错误
Error including correlation structure in function with gamm
我正在尝试创建自己的函数,其中包含 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 以使函数按预期运行有任何想法吗?谢谢!
您在构建公式时将向量与该向量的符号表示混淆了。
您不希望 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()
部分的问题,除了触发公式的计算代码有些不同。这里的指导原则是 总是 得到一个公式,如果不是用公式编程的话,你会输入它。你永远不会(也不应该)写出像
这样的公式
gamm(df[[var]] ~ x + s(z), ....)
虽然这在某些设置中可能有效,但如果您想要使用 predict()` 它将失败得很惨,而当您必须做一些更复杂的事情时它会失败。
我正在尝试创建自己的函数,其中包含 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 以使函数按预期运行有任何想法吗?谢谢!
您在构建公式时将向量与该向量的符号表示混淆了。
您不希望 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()
部分的问题,除了触发公式的计算代码有些不同。这里的指导原则是 总是 得到一个公式,如果不是用公式编程的话,你会输入它。你永远不会(也不应该)写出像
gamm(df[[var]] ~ x + s(z), ....)
虽然这在某些设置中可能有效,但如果您想要使用 predict()` 它将失败得很惨,而当您必须做一些更复杂的事情时它会失败。