繁体   English   中英

从 GAM 预测 R 中分组 dataframe 的值

[英]predict values from GAM for grouped dataframe in R

我有一个不同年份不同纬度的年平均温度值数据集。 我想用它来预测在给定年份可以找到给定温度的纬度; 即,“在 1980 年,年平均温度在 20C 的纬度是多少?”

我需要为此使用特定年份的模型,因为纬度和温度之间的关系随着时间的推移而变化(尽管下面的示例数据中没有,它是随机生成的)。 这将涉及:

  1. 将 GAM 拟合到按年份分组/拆分的数据集。
  2. 对于每个不同的 GAM(即每年),使用predict.gam计算温度列表中每个元素的预测值。
  3. 重新组合这些以获得 dataframe 列代表yearnewdata_value (用于predicted_value的温度值)和 predict_value (将每个newdata_value输入特定年份的 GAM 的纬度)。

这是一个玩具数据集:

years <- seq(1968, 2018, 1)
lat <- seq(34.5, 44.5, 1)
dat <- expand.grid(years, lat)
names(dat) <- c("years","lat")
dat$temp <- runif(dim(dat)[1], 5, 20) # add random temperature data points 
newdata_values <- seq(2, 16, 2) # temperature values to use for prediction

我尝试了各种purrrsplit-apply-combine解决方案,但没有想出任何办法。 有什么建议么?

另一种选择是安装 model,允许纬度/温度关系随年份变化。 有几种选择。 以下适合 model ,其中每年都有独立的关系:

gam(lat ~ year + s(temp, by = year), data = dat)

请注意,对于这个公式year应该被编码为一个因素。

另一种方法是允许纬度/温度关系逐年平稳变化,如果这种关系随时间逐渐变化,则为合理的 model。 在这种情况下,您将需要使用张量积平滑te() )来指示不同尺度(度、年)的变量之间的双向交互:

gam(lat ~ te(temp, year), data = dat)

在这两种情况下,您都可以使用predict.gam(model, newdata = new_dat)进行预测,其中new_datyeartemp列。

一种方法是使用嵌套数据框。 我使用了本教程中的代码。

您可以按年份分组并使用nest 我还将重命名列并添加新值以进行预测:

library(tidyverse); library(mgcv)
names(dat) <- c('year', 'lat', 'temp')
dat2 <- dat %>% group_by(year) %>% nest()

dat2 <- dat2 %>% mutate(newdata_value = rep(list(newdata_values), n_distinct(year)))

然后,您定义一些辅助函数以使 tidyverse 代码更清晰(我假设您使用的是mgcv包中的 gam)。 Then map the model function to the data and map the predict function to the fitted models:

lat_gam <- function(df) {
  gam(lat ~ s(temp), data = df)
}

pred_gam <- function(mod) {
  predict.gam(mod, newdata = data.frame(temp = newdata_values))
}

dat2 <- dat2 %>% mutate(model = map(data, lat_gam))

dat2 <- dat2 %>% mutate(predicted_value = map(model, pred_gam))


dat2 %>% select(-data, -model) %>% unnest(cols = c(newdata_value, predicted_value))

最后一行是完全可选的,只需按照您在 3) 中指定的方式打印最终的 output 即可

这是方法:

library(data.table)
library(mgcv)

setDT(dat)

dat[, .(pred = c(predict.gam(gam(lat ~ temp), list(temp = newdata_values))),
        newdata_values),
    by = years]

我遇到的唯一问题是predict.gam(...)调用返回一个数组。 c(predict.gam(...))将其转换为数组。

没有完美格式的类似基本方法:

by(dat[, -1],
   dat[, 1],
   function(DF) {
     mod = gam(lat ~ temp, data = DF)
     pred = predict.gam(mod, list(temp = newdata_values))

     data.frame(newdata_values, pred)
     }
   )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM