如何使用tidyverse堆叠多列?宽格式数据框列合并咨询
最优解决方案:用tidyverse的pivot_longer()重塑数据
这是典型的宽表转长表的结构化重塑问题,我推荐使用tidyverse生态中的tidyr::pivot_longer()函数来处理,代码简洁、易读且高效,是这类场景的最优选择。
完整代码示例
# 加载必要的包 library(tidyverse) # 生成你的示例数据 set.seed(1) df = data.frame(item=letters[1:6], field1a=sample(6,6),field1b=sample(60,6), field1c=sample(200,6), field2a=sample(6,6),field2b=sample(60,6), field2c=sample(200,6)) # 执行数据重塑 result_df <- df %>% pivot_longer( cols = -item, # 排除不需要重塑的item列 names_to = c("group", ".value"), # 拆分列名为分组和值列 names_pattern = "field(\\d)([a-c])" # 正则匹配拆分列名 ) %>% # 重命名列名到你想要的格式,同时移除临时的group列 select(item, fielda = a, fieldb = b, fieldc = c) # 查看结果 head(result_df)
代码解释
pivot_longer()核心参数:cols = -item:指定只对除item外的所有列进行重塑操作。names_to = c("group", ".value"):这里的.value是tidyr的特殊参数,表示拆分后的第二部分列名(a/b/c)要作为新的列名;group则用来临时存储原列名中的数字标识(1/2),对应原数据的field1和field2组。names_pattern = "field(\\d)([a-c])":用正则表达式精准匹配原列名结构:field是固定前缀,(\\d)捕获数字部分,([a-c])捕获后缀的a/b/c,完美拆分出我们需要的分组和值列信息。
select()收尾:把a/b/c重命名为你要求的fielda/fieldb/fieldc,并移除不需要的group列。
替代方案(Base R)
如果不想依赖tidyverse,也可以用Base R的reshape()函数,但代码会更繁琐,可读性也差一些:
result_base <- reshape(df, direction = "long", varying = list(c("field1a", "field2a"), c("field1b", "field2b"), c("field1c", "field2c")), v.names = c("fielda", "fieldb", "fieldc"), idvar = "item", timevar = "group") %>% select(-group)
结果验证
运行代码后,你会看到item=a的两行数据正好匹配你给出的示例:
# A tibble: 6 × 4 item fielda fieldb fieldc <chr> <int> <int> <int> 1 a 2 52 121 2 a 1 44 57 3 b 6 28 176 ...
内容的提问来源于stack exchange,提问作者santoku
相关产品推荐
相关产品推荐

