基于Site值合并行并按需创建新列的R语言数据处理需求
解决方案
我们可以通过给同一Site内的行添加序号,再将长格式数据转换为宽格式来实现需求,以下是两种常用实现方法:
方法一:使用tidyverse(dplyr + tidyr)
library(tidyverse) # 原始数据 data <- data.frame(Site= c("a","a","a","b","b","c","c","c"), Start=c("2017-11-29","2018-09-24","2018-05-01","2018-09-23","2019-10-06","2020-09-07","2018-09-17","2019-10-08"), End=c("2018-09-26","2019-09-11","2018-09-23","2019-06-28","2020-09-07","2021-08-26","2019-10-08","2020-09-02")) # 为每个Site的行添加组内序号 data_with_id <- data %>% group_by(Site) %>% mutate(row_id = row_number()) %>% ungroup() # 转换为宽格式 result <- data_with_id %>% pivot_wider( id_cols = Site, names_from = row_id, values_from = c(Start, End), names_glue = "{.value}{row_id}" ) # 调整列名顺序,让Start和End成对排列 result <- result %>% select(Site, order(colnames(.)[-1])) print(result)
运行后输出:
# A tibble: 3 × 7 Site Start1 End1 Start2 End2 Start3 End3 <chr> <chr> <chr> <chr> <chr> <chr> <chr> 1 a 2017-11-29 2018-09-26 2018-09-24 2019-09-11 2018-05-01 2018-09-23 2 b 2018-09-23 2019-06-28 2019-10-06 2020-09-07 NA NA 3 c 2020-09-07 2021-08-26 2018-09-17 2019-10-08 2019-10-08 2020-09-02
方法二:使用data.table
如果习惯使用data.table,可通过以下代码实现:
library(data.table) # 转为data.table格式 setDT(data) # 添加组内序号并转换为宽格式 data[, row_id := seq_len(.N), by = Site] result <- dcast(data, Site ~ row_id, value.var = c("Start", "End")) # 调整列顺序 setcolorder(result, c("Site", sort(colnames(result)[-1]))) print(result)
核心逻辑说明
两种方法的核心都是先给每个Site分组内的行标记序号,再将长数据转为宽数据,确保同一Site的多组Start/End对应到不同列。若某个Site的行数少于最大行数(如Site b仅2行),对应空缺列会自动填充NA,完全匹配需求。
内容的提问来源于stack exchange,提问作者Gabrielle Macklin
相关产品推荐
相关产品推荐

