如何在R语言中按分隔点将宽格式数据转换为长格式
R语言宽格式转长格式实现方案
现有如下宽格式数据集,需要转换为指定的长格式结构:
原始宽格式数据
data <- structure(list(lsoa11 = c("E01000001", "E01000002", "E01000003"), gpp_dist.16 = c(0.702954545454545, 0.929508196721311, 1.13484848484848), ed_dist.16 = c(2.15590909090909, 2.04475409836066, 2.53454545454545), gpp_dist.17 = c(0.701333333333333, 0.937966101694915, 1.10735294117647), ed_dist.17 = c(3.44755555555556, 3.12610169491525, 3.72970588235294)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
期望的长格式数据
data2 <- structure(list(lsoa11 = c("E01000001", "E01000002", "E01000003", "E01000001", "E01000002", "E01000003"), Year = c(16, 16, 16, 17, 17, 17), gpp_dist = c(0.702954545454545, 0.929508196721311, 1.13484848484848, 0.701333333333333, 0.937966101694915, 1.10735294117647), ed_dist = c(2.15590909090909, 2.04475409836066, 2.53454545454545, 3.44755555555556, 3.12610169491525, 3.72970588235294)), row.names = c(NA, 6L), class = "data.frame")
方法一:使用tidyr包的pivot_longer(推荐)
tidyr是tidyverse生态中的核心工具包,pivot_longer是专门用于宽转长的函数,语法简洁直观:
# 未安装tidyr的话先运行:install.packages("tidyr") library(tidyr) data_long <- pivot_longer( data, cols = -lsoa11, # 排除不需要转换的ID列 names_to = c(".value", "Year"), # .value保留原始变量名,Year存储拆分出的年份 names_sep = "\\." # 按点号拆分列名(正则中需转义) )
参数说明:
cols = -lsoa11:指定除lsoa11外的所有列参与格式转换;names_to = c(".value", "Year"):将原列名拆分为两部分,.value对应gpp_dist/ed_dist这类变量名,Year对应后缀的年份数字;names_sep = "\\.":指定列名的分隔符为点号,由于点号是正则特殊字符,需用反斜杠转义。
转换后的data_long结构与目标data2完全一致。
方法二:使用base R的reshape函数
若不想加载额外包,可使用R自带的reshape函数实现:
data_long <- reshape( data, direction = "long", varying = list(c("gpp_dist.16", "gpp_dist.17"), c("ed_dist.16", "ed_dist.17")), v.names = c("gpp_dist", "ed_dist"), idvar = "lsoa11", timevar = "Year", times = c(16, 17) ) # 调整行顺序并重置行名,匹配目标格式 data_long <- data_long[order(data_long$lsoa11), ] row.names(data_long) <- NULL
参数说明:
direction = "long":明确转换方向为长格式;varying:按变量分组列出需要转换的宽格式列;v.names:指定转换后的变量名称;idvar:指定用于标识唯一观测的ID列;timevar:指定存储年份的列名;times:指定年份的具体取值。
内容的提问来源于stack exchange,提问作者OLu
相关产品推荐
相关产品推荐

