R语言:将长格式DataFrame转宽格式并拼接列值生成新列
解决方案
方法一:使用tidyverse(推荐)
通过拉长数据→生成规范列名→转宽数据三步完成转换,代码可读性强,适合多数场景:
library(tidyverse) # 原始数据 df = data.frame(Process = rep("Global", 6), Category = c("Category_1", "Category_1", "Category_2", "Category_2", "Category_3", "Category_3"), Metric = c("Metric_1_1", "Metric_1_2", "Metric_2_1", "Metric_2_2", "Metric_3_1", "Metric_3_2"), level_1 = c(0.50, 0.50, 0.50, 0.50, 0.50, 0.50), level_2 = c(0.75, 0.50, 0.50, 0.50, 0.50, 0.50)) # 转换为目标格式 df_wide <- df %>% # 将level_1/level_2拆分为等级名称和对应数值 pivot_longer(cols = starts_with("level_"), names_to = "Level", values_to = "Value") %>% # 把等级名称格式化为Level_1/Level_2(首字母大写) mutate(Level = str_replace(Level, "level_", "Level_")) %>% # 拼接Process/Category/Metric/Level为新列名,用冒号分隔 unite(Colname, Process, Category, Metric, Level, sep = ":") %>% # 转成宽格式,每个新列名对应一个数值 pivot_wider(names_from = Colname, values_from = Value)
运行后得到的df_wide列名完全符合Global:Category_1:Metric_1_1:Level_1的格式要求,数值对应准确。
方法二:使用Base R
无需加载额外包,用基础R函数实现轻量转换:
# 原始数据 df = data.frame(Process = rep("Global", 6), Category = c("Category_1", "Category_1", "Category_2", "Category_2", "Category_3", "Category_3"), Metric = c("Metric_1_1", "Metric_1_2", "Metric_2_1", "Metric_2_2", "Metric_3_1", "Metric_3_2"), level_1 = c(0.50, 0.50, 0.50, 0.50, 0.50, 0.50), level_2 = c(0.75, 0.50, 0.50, 0.50, 0.50, 0.50)) # 生成所有目标列名 col_names <- apply(expand.grid(df$Process, df$Category, df$Metric, c("Level_1", "Level_2")), 1, paste, collapse = ":") # 提取所有数值并按列名顺序排列 values <- c(t(df[, c("level_1", "level_2")])) # 创建宽格式数据框 df_wide_base <- data.frame(t(values)) colnames(df_wide_base) <- col_names
补充说明
- tidyverse方法逻辑清晰,便于后续修改扩展;
- Base R方法无依赖,适合快速处理简单数据。
内容的提问来源于stack exchange,提问作者vic
相关产品推荐
相关产品推荐

