如何使用R分析长度不一致的两类时间序列的相关性
R语言异采样率不等长时间序列相关性计算报错解决方法
R内置的相关计算函数(包括cor()、cor.test()、基础互相关函数ccf())默认要求两个输入序列长度一致、观测一一对应,你手上的实测数据(3000点)和模型输出(40000点)采样间隔不同、时间轴未对齐,直接传入数值向量计算必然触发长度不匹配报错,解决核心是先基于时间基准对齐两个序列,再做相关计算,具体操作如下:
- 第一步先给两类数据绑定标准时间戳:不要靠点数硬凑对齐,先把两类数据都整理成「时间列+数值列」的两列结构,时间列统一转成POSIXct格式,严格对应每个数据点的实际观测/输出时间,不要手动估算时间偏移。
根据数据特性二选一完成序列对齐即可:
方案1:降采样高分辨率模型输出,匹配实测分辨率(优先选)
实测数据是直接观测得到的真值,分辨率更低,对它做插值会引入额外误差,因此优先把高分辨率的模型输出聚合到实测的时间步长上:
- 操作逻辑:以实测序列的每个时间点为基准,取该时间点对应时间窗口内的所有模型输出值做聚合(连续型变量比如气温、气压取窗口平均,累计型变量比如降水、径流量取窗口求和,数据噪声大可以取窗口中位数),最终得到和实测序列长度完全一致、时间点一一对应的模型匹配序列。
- 参考实现代码:
library(lubridate) library(dplyr) # 以下为示例数据结构,替换成你自己的实际数据即可 # 实测数据:按实际采样间隔设置by参数,示例为1小时间隔共3000点 obs <- data.frame( time = seq.POSIXt(from = ymd_hm("2020-01-01 00:00"), by = "hour", length.out = 3000), obs_val = rnorm(3000) ) # 模型输出:按实际输出间隔设置by参数,示例为5分钟间隔共40000点 model <- data.frame( time = seq.POSIXt(from = ymd_hm("2020-01-01 00:00"), by = "5 min", length.out = 40000), model_val = rnorm(40000) ) # 给模型数据标记对应到实测时间点的分组 model <- model %>% mutate(match_time = floor_date(time, unit = "hour")) # unit参数和实测采样间隔保持一致 # 聚合得到对齐后的模型序列 model_aligned <- model %>% group_by(match_time) %>% summarise(model_val_aligned = mean(model_val, na.rm = TRUE)) # 聚合函数按变量类型替换 # 合并得到等长的配对数据集 data_cor <- left_join(obs, model_aligned, by = c("time" = "match_time")) # 直接计算相关即可,自动剔除缺失值 cor(data_cor$obs_val, data_cor$model_val_aligned, use = "complete.obs")
方案2:升采样实测数据匹配模型分辨率(仅特殊需求用)
如果必须保留模型输出的高分辨率信息,可以对低分辨率的实测数据做插值,生成和模型序列等长的配对数据:
注意:该方法会因为插值引入人为误差,非必要不要选
- 操作逻辑:基于实测序列的时间-值对应关系,用线性插值、三次样条插值等方法,在模型输出的每个时间节点上估算对应的实测值,最终得到和模型序列等长的实测匹配序列。
- 参考实现代码:
library(zoo) # 将实测数据转为时间序列对象 obs_zoo <- zoo(obs$obs_val, order.by = obs$time) # 在模型的时间轴上插值得到高分辨率实测序列 obs_aligned <- na.approx(obs_zoo, xout = model$time) # 等长序列直接计算相关 cor(as.numeric(obs_aligned), model$model_val, use = "complete.obs")
禁止为了凑长度直接截短长序列、重复短序列值或者随机补值,这类操作完全破坏时间对应关系,算出的相关系数没有任何物理意义。对齐前先截取两个序列共有的时间重叠区间,非重叠段的数据直接丢弃即可。
如果需要计算滞后相关,完成时间对齐后直接调用ccf()函数即可,不会再触发长度报错。
内容的提问来源于stack exchange,提问作者Morhaf
相关产品推荐
相关产品推荐

