如何预测R中具有随机效应的gam模型?
How to predict gam model with random effect in R?
我正在研究预测 gam
具有随机效应的模型以通过 plot_ly
生成 3D 曲面图。
这是我的代码;
x <- runif(100)
y <- runif(100)
z <- x^2 + y + rnorm(100)
r <- rep(1,times=100) # random effect
r[51:100] <- 2 # replace 1 into 2, making two groups
df <- data.frame(x, y, z, r)
gam_fit <- gam(z ~ s(x) + s(y) + s(r,bs="re"), data = df) # fit
#create matrix data for `add_surface` function in `plot_ly`
newx <- seq(0, 1, len=20)
newy <- seq(0, 1, len=30)
newxy <- expand.grid(x = newx, y = newy)
z <- matrix(predict(gam_fit, newdata = newxy), 20, 30) # predict data as matrix
然而,最后一行导致错误;
Error in model.frame.default(ff, data = newdata, na.action = na.act) :
variable lengths differ (found for 'r')
In addition: Warning message:
In predict.gam(gam_fit, newdata = newxy) :
not all required variables have been supplied in newdata!
多亏了之前的回答,我确信上面的代码没有随机效果,如 .
如何预测具有随机效应的 gam 模型?
假设您希望表面以随机效应为条件(但不是随机效应的特定级别),有两种方法。
第一个是为随机效应提供一个水平,但使用 predict.gam()
的 exclude
参数从预测值中排除该项。第二种是再次使用 exclude
,但这次不提供任何随机效应数据,而是使用参数 newdata.guaranteed = TRUE
.[= 停止 predict.gam()
检查 newdata
25=]
选项 1:
newxy1 <- with(df, expand.grid(x = newx, y = newy, r = 2))
z1 <- predict(gam_fit, newdata = newxy1, exclude = 's(r)')
z1 <- matrix(z1, 20, 30)
选项 2:
z2 <- predict(gam_fit, newdata = newxy, exclude = 's(r)',
newdata.guaranteed=TRUE)
z2 <- matrix(z2, 20, 30)
这些产生相同的结果:
> all.equal(z1, z2)
[1] TRUE
一些注意事项:
您使用哪个将取决于您模型其余部分的复杂程度。我通常会使用第一个选项,因为它提供了额外的检查,防止我在创建数据时做一些愚蠢的事情。但是在这种情况下,使用一个简单的模型和一组协变量似乎足够安全,可以相信 newdata
没问题。
您的示例使用随机斜率(这是故意的吗?),而不是随机截距,因为 r
不是一个因素。如果您的真实示例使用因子随机效应,那么您在创建 newdata
时需要更加小心,因为您需要正确获得因子的 levels
。例如:
expand.grid(x = newx, y = newy,
r = with(df, factor(2, levels = levels(r))))
应该为因素 r
设置正确的设置
我正在研究预测 gam
具有随机效应的模型以通过 plot_ly
生成 3D 曲面图。
这是我的代码;
x <- runif(100)
y <- runif(100)
z <- x^2 + y + rnorm(100)
r <- rep(1,times=100) # random effect
r[51:100] <- 2 # replace 1 into 2, making two groups
df <- data.frame(x, y, z, r)
gam_fit <- gam(z ~ s(x) + s(y) + s(r,bs="re"), data = df) # fit
#create matrix data for `add_surface` function in `plot_ly`
newx <- seq(0, 1, len=20)
newy <- seq(0, 1, len=30)
newxy <- expand.grid(x = newx, y = newy)
z <- matrix(predict(gam_fit, newdata = newxy), 20, 30) # predict data as matrix
然而,最后一行导致错误;
Error in model.frame.default(ff, data = newdata, na.action = na.act) :
variable lengths differ (found for 'r')
In addition: Warning message:
In predict.gam(gam_fit, newdata = newxy) :
not all required variables have been supplied in newdata!
多亏了之前的回答,我确信上面的代码没有随机效果,如
如何预测具有随机效应的 gam 模型?
假设您希望表面以随机效应为条件(但不是随机效应的特定级别),有两种方法。
第一个是为随机效应提供一个水平,但使用 predict.gam()
的 exclude
参数从预测值中排除该项。第二种是再次使用 exclude
,但这次不提供任何随机效应数据,而是使用参数 newdata.guaranteed = TRUE
.[= 停止 predict.gam()
检查 newdata
25=]
选项 1:
newxy1 <- with(df, expand.grid(x = newx, y = newy, r = 2))
z1 <- predict(gam_fit, newdata = newxy1, exclude = 's(r)')
z1 <- matrix(z1, 20, 30)
选项 2:
z2 <- predict(gam_fit, newdata = newxy, exclude = 's(r)',
newdata.guaranteed=TRUE)
z2 <- matrix(z2, 20, 30)
这些产生相同的结果:
> all.equal(z1, z2)
[1] TRUE
一些注意事项:
您使用哪个将取决于您模型其余部分的复杂程度。我通常会使用第一个选项,因为它提供了额外的检查,防止我在创建数据时做一些愚蠢的事情。但是在这种情况下,使用一个简单的模型和一组协变量似乎足够安全,可以相信
newdata
没问题。您的示例使用随机斜率(这是故意的吗?),而不是随机截距,因为
r
不是一个因素。如果您的真实示例使用因子随机效应,那么您在创建newdata
时需要更加小心,因为您需要正确获得因子的levels
。例如:expand.grid(x = newx, y = newy, r = with(df, factor(2, levels = levels(r))))
应该为因素
r
设置正确的设置