R语言中将长格式数据转换为数组而非宽表的实现方法
R语言将长格式数据转换为多维数组(按变量拆分二维表)
先看原始数据:
test_df <- data.frame( dates = c(19801230,19801231,19801231,19810101), ID = c(101,101,102,102), var1 = 0:3, var2 = 5:8 )
下面给三种可行方案,避开复杂的维度匹配问题:
方案1:tidyr + abind 分步构建
先把每个变量转成宽表,再合并成三维数组:
library(tidyr) library(abind) # 定义要转换的变量列表 target_vars <- c("var1", "var2") # 逐个生成变量对应的宽表(行=日期,列=ID,缺值填NA) wide_tables <- lapply(target_vars, function(var) { pivot_wider(test_df, id_cols = dates, names_from = ID, values_from = all_of(var), values_fill = NA) %>% column_to_rownames("dates") %>% as.matrix() }) # 按第三个维度合并成数组,添加维度名称 final_array <- abind(wide_tables, along = 3) dimnames(final_array) <- list( dates = unique(test_df$dates), ID = unique(test_df$ID), variables = target_vars ) # 查看结果 final_array
方案2:reshape2 一键生成(最简洁)
用acast直接从长格式转三维数组,一步到位:
library(reshape2) # 先把数据熔化为更长格式(每个变量的观测单独一行) melted_data <- melt(test_df, id.vars = c("dates", "ID")) # 生成三维数组,指定行=dates,列=ID,第三维度=variable,缺值填充NA final_array2 <- acast(melted_data, dates ~ ID ~ variable, fill = NA) # 查看结果 final_array2
方案3:纯基础R手动实现(无依赖)
不想装包的话,手动初始化数组再填充值:
# 获取所有唯一的日期、ID和变量 unique_dates <- unique(test_df$dates) unique_ids <- unique(test_df$ID) target_vars <- c("var1", "var2") # 初始化空数组,设置维度和名称 final_array3 <- array( NA, dim = c(length(unique_dates), length(unique_ids), length(target_vars)), dimnames = list( dates = unique_dates, ID = unique_ids, variables = target_vars ) ) # 循环填充每个变量的数值 for (i in seq_along(target_vars)) { current_var <- target_vars[i] # 提取当前变量的日期、ID和对应值 sub_data <- test_df[, c("dates", "ID", current_var)] # 匹配行和列的索引位置 row_pos <- match(sub_data$dates, unique_dates) col_pos <- match(sub_data$ID, unique_ids) # 填充到数组对应位置 final_array3[row_pos, col_pos, i] <- sub_data[[current_var]] } # 查看结果 final_array3
三个方案都能得到你要的结构:每个变量对应数组的一层二维表,行是所有日期,列是所有ID,缺失值自动填充NA。
内容的提问来源于stack exchange,提问作者oibaFox
相关产品推荐
相关产品推荐

