R语言实现含复合列名的宽格式数据转指定结构长格式
宽表转指定结构长表的自动化实现方案
两种成熟实现路径,均适配大体量数据,无需手动枚举列名:
方案1:tidyverse 实现(推荐,千万级行数据处理效率高)
核心用pivot_longer做长宽转换,通过正则自动从列名拆分出coef和model字段,代码如下:
library(dplyr) library(tidyr) data_long <- data %>% pivot_longer( cols = !id, names_to = "tmp_col", values_to = "value" ) %>% mutate( coef = paste0(sub("_p_.*", "", tmp_col), "_p_"), model = sub(".*_p_", "", tmp_col) ) %>% select(id, model, coef, value)
运行结果完全匹配要求的结构,id=1对应的记录如下:
id model coef value 1 1 model1 fact_1_p_ 1 2 1 model1 ra_2_p_ 5 3 1 model2 da_1_p_ 3 4 1 model2 dd_2_p_ 4 5 1 nonlinearmodel1 fact_1_p_ 4 6 1 nonlinearmodel1 tt_2_p_ 3 7 1 nonlinearmodel2 fact_1_p_ 1 8 1 nonlinearmodel2 rara_2_p_ 9
方案2:基础R实现(无第三方包依赖)
如果不方便安装扩展包,可以直接用基础R的reshape函数实现,逻辑和上面一致:
# 提取所有待转换的指标列名 metric_cols <- setdiff(names(data), "id") # 自动拆分列名得到两个标识向量 coef_set <- paste0(sub("_p_.*", "", metric_cols), "_p_") model_set <- sub(".*_p_", "", metric_cols) # 长宽转换 data_long <- reshape( data, direction = "long", varying = metric_cols, v.names = "value", timevar = "col_index", times = seq_along(metric_cols), idvar = "id" ) # 匹配填入标识字段 data_long$coef <- coef_set[data_long$col_index] data_long$model <- model_set[data_long$col_index] # 清理冗余字段,调整列顺序 data_long <- data_long[, c("id", "model", "coef", "value")] rownames(data_long) <- NULL
适配说明
- 上述代码默认所有指标列命名遵循
[系数前缀]_p_[模型标识]的规则,和给出的示例命名完全一致,真实数据只要保持这个命名规则,不管有多少列、多少行数据都可以自动处理,不需要手动修改列名映射。 - 如果后续命名规则调整,只需要修改
sub函数里的正则匹配规则即可,整体转换逻辑不需要改动。
内容的提问来源于stack exchange,提问作者yoo
相关产品推荐
相关产品推荐

