【问题标题】:How can I append fitted GAM model values back to each group?如何将拟合的 GAM 模型值附加回每个组?
【发布时间】:2021-03-10 04:15:02
【问题描述】:

我在三年内对多个站点 (siteID) 的一些数据 (Var1) 进行了每日观察,并根据一年中的某天 (DoY) 为每个站点拟合了一个广义相加模型 (GAM) .如何将拟合的 gam 值附加回原始数据框?

这是一些示例数据:

library(mgcv)
library(dplyr)

df <- data.frame(matrix(ncol = 4, nrow = 2190))
x <- c("siteID", "DoY", "Var1", "gam_fitted_var1")
colnames(df) <- x
df[1:1095,1] <- rep("A",1095)
df[1096:2190,1] <- rep("B",1095)
df$DoY <- rep(seq(from = 1, to = 365, by = 1),6)
set.seed(123)
a <- 10  # amplitude
b = 2*pi/365
c = 1
d = rnorm(365,2,2)
aa = 4
dd = rnorm(365,4,1)
e <- rep(seq(1,365,1),3)
y1 <- a*sin(b*(e-c))+d
y2 <- aa*sin(b*(e-c))+dd
df[1:1095,3] <- y1
df[1096:2190,3] <- y2

我将每个组的 GAM 拟合如下:

df2 <- df %>%
  group_by(siteID) %>%
  do(gam_mod = gam(Var1 ~ s(DoY, bs = 'cc'), data = .)) %>%
  ungroup

如何从 GAM 输出中获取“fitted.values”并将它们附加回原始数据框 (df)?我知道如何手动执行此操作,如下所示,但我的真实数据集有 100 个组(即siteID),我希望避免为每个站点手动执行此操作。

df[1:1095,4] <- df2[[2]][[1]][["fitted.values"]]
df[1096:2190,4] <- df2[[2]][[2]][["fitted.values"]]

【问题讨论】:

    标签: r dplyr mgcv


    【解决方案1】:

    使用sapply 从每个gam_mod 中提取"fitted.values" 并添加为新列。

    df$gam_fitted_var1 <- c(sapply(df2$gam_mod, `[[`, "fitted.values"))
    

    【讨论】:

    • 你最好使用fitted()方法来提取这些而不是抓取特定的组件
    • @GavinSimpson 我试过做fitted(df2$gam_mod),但输出是NULL。您能否详细说明在此示例中如何使用它从 GAM 模型输出列表中提取fitted.values?这种方法还有什么好处?
    • 如果df2$gam_mod 继承自"gam" 类,那么这应该有效,但我不清楚您的do() 步骤会产生什么结果。您需要遵循答案和sapply() 但是而不是使用[[ 进行子集化,而是使用fitted,如sapply(df2$gam_mod, fitted)gam_mod 显然不是拟合模型,而是我认为的模型列表?
    • @GavinSimpson 是的,do() 步骤会生成一个 gam 模型列表,并且执行c(sapply(df2$gam_mod, fitted)) 提供的结果与@RonakShah 描述的结果相同。这两个答案的奇怪之处在于,当我将它们应用于具有 100 多个游戏模型的真实数据集时,两个答案都不起作用。我收到一个错误,即现有数据有 x 行,而分配的数据有 y 行(y 值是do() 函数生成的游戏模型的数量)。我也许可以用 for 循环解决这个问题,并在我有答案时发布答案。
    猜你喜欢
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 2014-02-20
    • 2017-01-10
    • 2019-07-07
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多