首页 > 解决方案 > 如何将 GAM 模型拟合到多对 (x,y) 变量

问题描述

我试图通过首先拟合第一对然后移动到第二对来将 GAM 模型拟合到由两对 (x,y) 值即 (x1,y1) 和 (x2,y2) 组成的数据集。当我在“for”循环中调用 gam 函数时,它会给出一个错误“没有足够的(非 NA)数据来做任何有意义的事情”。我怀疑这与我构造列的 x1、y1、x2 和 y2 标签的方式有关,因为在“for”循环之外,gam 函数可以工作。

谢谢!

library(mgcv)
#> Loading required package: nlme
#> This is mgcv 1.8-26. For overview type 'help("mgcv-package")'.
library(ggplot2)
library(tidyverse)

# create dataframe
x1 = seq(0, 50, by = 0.5)
y1 = dnorm(x1, mean = 22, sd = 5)
x2 = seq(0, 50, by = 0.5)
y2 = dnorm(x2, mean = 28, sd = 7)
df = cbind.data.frame(x1, y1, x2, y2)

# plot(c(x1,x2), c(y1,y2))

count = ncol(df)/2
for (i in 1:count) {
  x<-noquote(paste("x", i, sep = ""))
  y<-noquote(paste("y", i, sep = ""))
  print(x)  # test
  gam(y ~ s(x), data = df, method = "REML")   # this call doesn't work
}

gam(y1 ~ s(x1), data = df, method = "REML")   # this call works

标签: r

解决方案


我已经设法找出问题所在。事实证明,我对 xi 和 yi 变量的构造导致了问题,因为 y ~ s(x) 不是“公式”类型。我必须在 gam 函数调用之外构建方程,将其转换为“公式”类型,然后在 gam 调用中使用它。

library(mgcv)
library(ggplot2)
library(tidyverse)

# create test dataframe
x1 = seq(0, 50, by = 0.5)
y1 = dnorm(x1, mean = 25, sd = 5)
x2 = seq(0, 50, by = 0.5)
y2 = dnorm(x2, mean = 29, sd = 7)
df = cbind.data.frame(x1, y1, x2, y2)

plot(c(df$x1,df$x2), c(df$y1,df$y2))

(count = ncol(df)/2)
for (i in 1:count) {
  # construct the formula to go into the "gam" function and convert it to type "formula" with the "as.formula" function
  part1 <- noquote(paste0("y", i))
  part2 <- paste0("~ s(")
  frag1 <- paste(part1, part2)
  part3 <- noquote(paste0("x", i))
  frag2 <- paste0(frag1, part3)
  frag3 <- paste0(frag2, ")")
  fmla <- as.formula(frag3)
  
  # fit the data
  gam_mod <- gam(formula = fmla, data = df, method = "REML")
  
  print(gam_mod)
}

推荐阅读