使用pivot_longer()展开数据行并合并模式化列
问题:将重复列组转换为长格式数据框
原始数据框:
ID Email Name Company TripIdentifier Date1 Campsite1 NumberOfAnimals1 Date2 Campsite2 NumberOfAnimals2 1 1 user1@example.com Alice Company A Trip 1 2022-01-01 Campsite A 5 2022-01-02 Campsite C 5 2 2 user2@example.com Bob Company B Trip 2 2022-01-02 Campsite B 5 2022-01-03 Campsite D 5
希望转换为以下长格式:
ID Email Name Company TripIdentifier Date Campsite NumberOfAnimals 1 1 user1@example.com Alice Company A Trip 1 2022-01-01 Campsite A 5 2 1. user1@example.com Alice Company A Trip 1 2022-01-02 Campsite C 5 3 2. user2@example.com Bob Company B Trip 2 2022-01-02 Campsite B 5 4 2. user2@example.com Bob Company B Trip 2 2022-01-03 Campsite D 5
问题分析
你之前的代码仅选中starts_with("Date")的列进行重塑,因此只处理了Date相关列,未覆盖Campsite和NumberOfAnimals的重复列组。pivot_longer()支持一次性处理所有同模式的重复列组,核心是选中全部目标列并正确匹配列名规则。
解决方案
使用pivot_longer()时需注意:
- 选中所有需要重塑的列(Date、Campsite、NumberOfAnimals开头且带数字后缀的列)
- 通过
names_pattern匹配列名的前缀(如Date、Campsite)和数字后缀(如1、2) - 用
.value保留前缀作为新列名,用临时变量存储数字后缀区分组
完整代码如下:
library(tidyverse) # 定义测试数据框 Test <- data.frame( ID = c(1, 2), Email = c("user1@example.com", "user2@example.com"), Name = c("Alice", "Bob"), Company = c("Company A", "Company B"), TripIdentifier = c("Trip 1", "Trip 2"), Date1 = as.Date(c("2022-01-01", "2022-01-02")), Campsite1 = c("A", "B"), NumberOfAnimals1 = c(5, 5), Date2 = as.Date(c("2022-01-02", "2022-01-03")), Campsite2 = c("C", "D"), NumberOfAnimals2 = c(5, 5), stringsAsFactors = FALSE ) # 执行数据重塑 reshaped <- Test %>% pivot_longer( cols = matches("^(Date|Campsite|NumberOfAnimals)\\d+$"), # 匹配所有目标列 names_to = c(".value", "trip"), # .value保留列前缀,trip存储数字后缀 names_pattern = "(.*)(\\d+)$" # 匹配前缀和数字后缀的正则规则 ) %>% # 可选:生成目标格式的ID(原ID加.,每组第一行保留原ID) group_by(ID) %>% mutate(ID = ifelse(row_number() == 1, as.character(ID), paste0(ID, "."))) %>% ungroup() %>% select(-trip) # 移除临时的trip列 # 查看结果 print(reshaped)
输出说明
运行后将得到目标长格式数据:
- 所有重复列组被合并为
Date、Campsite、NumberOfAnimals三列 - 每行对应原数据中一条独立的露营记录
- 可选的ID处理步骤实现了目标中的
1、1.、2.样式
内容的提问来源于stack exchange,提问作者R Beginner
相关产品推荐
相关产品推荐

