如何基于一维时间序列生成指定形状的滞后数组?含二维扩展需求
问题描述
现有如下R语言数据:
> data <- dplyr::tibble(v = c(1:10)) > data # A tibble: 10 × 1 v <int> 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
需要创建一个形状为11x5x1的数组,每行遵循如下模式:
NA NA NA NA NA NA NA NA NA 1 NA NA NA 1 2 NA NA 1 2 3 NA 1 2 3 4 1 2 3 4 5 ....
解决方案
一、一维数据生成目标数组
方法1:批量向量操作(高效推荐)
通过构造索引矩阵批量取值,超出原始数据范围的自动设为NA:
# 定义核心参数 n_rows <- 11 n_cols <- 5 vec <- data$v # 生成每行的起始索引(包含负数,对应前导NA的情况) start_indices <- seq(from = 0 - (n_cols - 1), to = length(vec) - n_cols + 1) # 构造所有元素的位置索引矩阵 idx_matrix <- outer(start_indices, 0:(n_cols-1), FUN = "+") # 生成结果矩阵,过滤无效索引并填充NA result_matrix <- matrix(ifelse(idx_matrix > 0 & idx_matrix <= length(vec), vec[idx_matrix], NA), nrow = n_rows, ncol = n_cols) # 转换为11x5x1的数组 result_array <- array(result_matrix, dim = c(n_rows, n_cols, 1)) # 查看结果的第一维度 print(result_array[, , 1])
输出结果符合要求:
[,1] [,2] [,3] [,4] [,5] [1,] NA NA NA NA NA [2,] NA NA NA NA 1 [3,] NA NA NA 1 2 [4,] NA NA 1 2 3 [5,] NA 1 2 3 4 [6,] 1 2 3 4 5 [7,] 2 3 4 5 6 [8,] 3 4 5 6 7 [9,] 4 5 6 7 8 [10,] 5 6 7 8 9 [11,] 6 7 8 9 10
方法2:循环填充(直观易懂)
如果对向量操作不熟悉,逐行循环填充逻辑更清晰:
result_matrix <- matrix(NA, nrow = 11, ncol = 5) vec <- data$v for (i in 1:11) { # 计算当前行的起始位置 start_pos <- i - 5 # 截取有效元素范围 elements <- vec[max(1, start_pos):min(start_pos + 4, 10)] # 填充前导NA和有效元素 result_matrix[i, ] <- c(rep(NA, 5 - length(elements)), elements) } # 转换为目标数组 result_array <- array(result_matrix, dim = c(11,5,1))
二、二维时间序列的扩展
假设二维时间序列是多变量时间步数据,比如:
# 示例:10个时间步,3个变量 ts_2d <- dplyr::tibble(v1 = 1:10, v2 = 11:20, v3 = 21:30)
要生成形状为11x5x3的数组(11个窗口、5个时间步、3个变量),可以对每个变量单独应用一维逻辑后合并:
循环实现
n_rows <- 11 window_size <- 5 n_vars <- ncol(ts_2d) ts_matrix <- as.matrix(ts_2d) # 初始化结果数组 result_array_2d <- array(NA, dim = c(n_rows, window_size, n_vars)) # 逐个变量处理 for (var in 1:n_vars) { vec <- ts_matrix[, var] start_indices <- seq(from = 0 - (window_size - 1), to = length(vec) - window_size + 1) idx_matrix <- outer(start_indices, 0:(window_size-1), FUN = "+") var_matrix <- matrix(ifelse(idx_matrix > 0 & idx_matrix <= length(vec), vec[idx_matrix], NA), nrow = n_rows, ncol = window_size) result_array_2d[, , var] <- var_matrix } # 查看第一个变量的窗口结果 print(result_array_2d[, , 1])
高效apply实现
用apply替代循环,代码更简洁:
result_array_2d <- apply(ts_matrix, 2, function(vec) { start_indices <- seq(from = 0 - (window_size - 1), to = length(vec) - window_size + 1) idx_matrix <- outer(start_indices, 0:(window_size-1), FUN = "+") matrix(ifelse(idx_matrix > 0 & idx_matrix <= length(vec), vec[idx_matrix], NA), nrow = n_rows, ncol = window_size) }) # 调整维度顺序为11x5x3 result_array_2d <- aperm(result_array_2d, c(1,2,3))
内容的提问来源于stack exchange,提问作者Ai4l2s
相关产品推荐
相关产品推荐

