如何为R中dtwclust聚类准备不等长/异采样率时间序列
用data.table或lapply转换长格式数据为dtwclust所需的tslist结构
核心思路
dtwclust要求的tslist本质是每个元素对应一条时间序列的列表,每条序列可以是普通数值向量(因为你提到日期时间无关,仅保留数值的顺序即可)。我们只需要按时间序列的分组标识,把每组的数值提取出来组成列表即可。
假设数据结构
假设你的长格式data.table包含以下列:
group_id: 区分不同时间序列的唯一标识minute_index: 分钟索引(用于保证数值顺序)value: 时间序列的观测值
示例数据:
library(data.table) set.seed(123) dt <- data.table( group_id = rep(c("seq1", "seq2", "seq3"), c(8, 12, 6)), minute_index = c(seq(0, 105, 15), seq(0, 330, 30), seq(0, 75, 15)), value = rnorm(26) )
方法1:用data.table分组操作实现
这是最高效的方式,利用data.table的分组特性直接生成列表:
library(dtwclust) # 先按分组和分钟索引排序,确保数值顺序正确 dt_sorted <- dt[order(group_id, minute_index)] # 按group_id分组,提取每组的value并组成列表 ts_list <- dt_sorted[, list(ts = list(value)), by = group_id]$ts # 验证结构:dtwclust会将此识别为有效的tslist str(ts_list)
方法2:用lapply系列函数实现
如果你更熟悉基础R的循环操作,也可以用lapply完成:
# 获取所有唯一的分组标识 unique_groups <- unique(dt$group_id) # 循环提取每个分组的value,并按分钟索引排序 ts_list <- lapply(unique_groups, function(g) { subset_dt <- dt[group_id == g] subset_dt_sorted <- subset_dt[order(minute_index)] subset_dt_sorted$value }) # 可以给列表元素命名,方便后续识别 names(ts_list) <- unique_groups
关键说明
- 不需要使用tsibble:dtwclust不需要时间序列对象的时间戳信息,只要数值按顺序排列的向量即可满足聚类需求。
- 采样频率差异不影响:dtwclust的DTW算法本身支持不等长、不同采样频率的时间序列聚类,只要每条序列的数值顺序正确即可。
内容的提问来源于stack exchange,提问作者Meep
相关产品推荐
相关产品推荐

