Nest 模型 dplyr 校准和验证
Nest models dplyr calibration and validation
我用了很多 R,但我正在开始我的 tidyverse 之旅。
我正在尝试创建一个允许我对每日降水系列进行偏差校正的功能。
我想打破 2 中的时间序列(用于校准和验证)。我需要为校准期拟合模型,将其与观察和建模数据一起应用于验证期。
到目前为止,我能够在两个 for 循环中执行此操作,但我想知道是否可以使用 nest
来执行此“整理器”,但我无法弄清楚。
此外,我如何使用 apply 将其计算到 data.frame 中的许多降水时间序列。
我当前的代码如下,
提前致谢!
图书馆
library(lubridate)
library(qmap)
library(dplyr)
模拟数据
obs_ <- runif(min=0,max=157,n=14975)
sim <- obs_ + 20
date_ <- seq(as.Date("1979-01-01"), as.Date("2019-12-31"),by="days")
db <- data.frame(obs=obs_, sim=sim_, date=date_, month=month(date_), year=year(date_))
样本年
ss<- seq(from=1979, to=2019, by=1)
samp <- sample(ss, length(ss)/2)
samp <- samp[order(samp)]
samp1 <- subset(ss, !(ss %in% samp))
型号
list_mod <- list()
for(i in 1:12){
# retrives the data for the calibration period
model_fit <-db %>%
mutate(id = case_when( year %in% samp ~ "cal",
year %in% samp1 ~ "val")) %>%
filter(month== i, id== "cal")
# fits the model to each month and stores it in a list
list_mod[[i]] <- fitQmap(model_fit$obs,model_fit$sim)
}
检索有效期内的数据
model1 <- db %>%
mutate(id = case_when( year %in% samp ~ "cal",
year %in% samp1 ~ "val")) %>%
filter(id=="val")
估计新数据并将其与观察和模拟一起存储
for( i in 1:12){
temp__ <- model1[model1$month ==i,"sim"]
model1[model1$month ==i,"model"] <- doQmap(temp__, list_mod[[i]])
}
如果您不拘泥于 tidy
,这里有一个使用 data.table
的解决方案。
使用您的db
:
library(data.table)
library(qmap)
##
setDT(db)[, Set:='cal']
db[sample(.N, .N/2), Set:='val']
db[, pred:=doQmap(sim, fitQmap(obs[Set=='cal'], sim[Set=='cal'])), by=.(month)]
result <- db[Set=='val']
第一行将您的 db
转换为 data.table
并创建一个列 Set
来定义 calibration/validation。第二行将数据的随机 1/2 分配给验证集。
第三行完成所有工作:它按月对行进行分组 (by=.(month)
),然后在校准集上生成与 fitQmap(...)
的拟合,然后使用 [=19] 生成去偏预测=] 在完整数据集上。
最后一行只是过滤掉校准行。
我注意到在这个例子中 Qmap 减少了但没有消除偏差。是你期待的吗?
我用了很多 R,但我正在开始我的 tidyverse 之旅。
我正在尝试创建一个允许我对每日降水系列进行偏差校正的功能。
我想打破 2 中的时间序列(用于校准和验证)。我需要为校准期拟合模型,将其与观察和建模数据一起应用于验证期。
到目前为止,我能够在两个 for 循环中执行此操作,但我想知道是否可以使用 nest
来执行此“整理器”,但我无法弄清楚。
此外,我如何使用 apply 将其计算到 data.frame 中的许多降水时间序列。
我当前的代码如下,
提前致谢!
图书馆
library(lubridate)
library(qmap)
library(dplyr)
模拟数据
obs_ <- runif(min=0,max=157,n=14975)
sim <- obs_ + 20
date_ <- seq(as.Date("1979-01-01"), as.Date("2019-12-31"),by="days")
db <- data.frame(obs=obs_, sim=sim_, date=date_, month=month(date_), year=year(date_))
样本年
ss<- seq(from=1979, to=2019, by=1)
samp <- sample(ss, length(ss)/2)
samp <- samp[order(samp)]
samp1 <- subset(ss, !(ss %in% samp))
型号
list_mod <- list()
for(i in 1:12){
# retrives the data for the calibration period
model_fit <-db %>%
mutate(id = case_when( year %in% samp ~ "cal",
year %in% samp1 ~ "val")) %>%
filter(month== i, id== "cal")
# fits the model to each month and stores it in a list
list_mod[[i]] <- fitQmap(model_fit$obs,model_fit$sim)
}
检索有效期内的数据
model1 <- db %>%
mutate(id = case_when( year %in% samp ~ "cal",
year %in% samp1 ~ "val")) %>%
filter(id=="val")
估计新数据并将其与观察和模拟一起存储
for( i in 1:12){
temp__ <- model1[model1$month ==i,"sim"]
model1[model1$month ==i,"model"] <- doQmap(temp__, list_mod[[i]])
}
如果您不拘泥于 tidy
,这里有一个使用 data.table
的解决方案。
使用您的db
:
library(data.table)
library(qmap)
##
setDT(db)[, Set:='cal']
db[sample(.N, .N/2), Set:='val']
db[, pred:=doQmap(sim, fitQmap(obs[Set=='cal'], sim[Set=='cal'])), by=.(month)]
result <- db[Set=='val']
第一行将您的 db
转换为 data.table
并创建一个列 Set
来定义 calibration/validation。第二行将数据的随机 1/2 分配给验证集。
第三行完成所有工作:它按月对行进行分组 (by=.(month)
),然后在校准集上生成与 fitQmap(...)
的拟合,然后使用 [=19] 生成去偏预测=] 在完整数据集上。
最后一行只是过滤掉校准行。
我注意到在这个例子中 Qmap 减少了但没有消除偏差。是你期待的吗?