如何在R语言中将多维data.frame转换为一维data.frame
R语言实现数据格式转换方案
嗨,这个需求本质上是把宽格式的多维数据框转换成符合tidy数据规范的长格式,我给你梳理下具体的操作步骤,用R语言就能轻松搞定:
第一步:先处理特殊的两行表头
你的原始数据有两行表头(日期行和污染物类型行),得先把它们合并成清晰的复合列名,不然后续处理会混乱:
# 假设你已经把数据读进R里了(比如用read.csv(header=FALSE)读取,因为有两行表头) # 提取第一行的日期信息(从第三列开始) dates <- df1[1, -c(1, 2)] # 提取第二行的污染物类型信息(从第三列开始) types <- df1[2, -c(1, 2)] # 提取实际的数据行(跳过前两行表头) data_rows <- df1[-c(1, 2), ] # 给数据行设置列名:前两列是site和站点编码(你原始里的date列其实是站点标识),后面是日期+类型的复合名 colnames(data_rows) <- c("site", "site_code", paste(dates, types)) # 把数值列转成数值类型(避免后续计算出问题) data_rows[, -c(1, 2)] <- lapply(data_rows[, -c(1, 2)], as.numeric)
第二步:用tidyr包重塑数据
推荐用tidyverse生态里的tidyr::pivot_longer函数,这是目前最常用的宽转长工具:
library(tidyr) library(dplyr) # 辅助调整列顺序 # 执行宽转长操作 df_final <- data_rows %>% pivot_longer( cols = -c(site, site_code), # 保留site和站点编码列 names_sep = " ", # 拆分复合列名的分隔符(我们之前用空格合并的) names_to = c("date", "type"), # 拆分后分别对应监测日期和污染物类型 values_to = "value" # 存储数值的列名 ) %>% # 调整列的顺序,和你期望的输出完全匹配 select(site, site_code, date, type, value)
备选方案:用reshape2包的melt函数
如果你习惯用旧一点的reshape2包,也可以这么写:
library(reshape2) # 先转成初步的长格式 df_melted <- melt(data_rows, id.vars = c("site", "site_code"), variable.name = "date_type", value.name = "value") # 拆分复合列名成日期和类型 df_melted <- cbind(df_melted, colsplit(df_melted$date_type, " ", c("date", "type"))) # 调整列顺序得到最终结果 df_final <- df_melted %>% select(site, site_code, date, type, value)
小提示
- 如果合并列名时用的不是空格(比如下划线),记得对应修改
names_sep或者colsplit的分隔符; - 如果你的数据是从Excel导入的,也可以先在Excel里把两行表头合并成一行(比如改成
2019-01-01_PM2.5),再读入R处理,步骤会更简单。
内容的提问来源于stack exchange,提问作者jinchi
相关产品推荐
相关产品推荐

