R语言如何将数据框中连续年份行转换为对应类别的时间跨度
解决方案
核心思路
将连续年份且类别相同的记录划分为同一个分组,再按分组聚合取最小年份为起始年、最大年份为结束年,即可得到目标格式,无需手动编写循环。
tidyverse 实现(推荐,代码简洁易读)
library(dplyr) # 构造示例数据 cat <- c("Cat1","Cat1","Cat2","Cat2","Cat2","Cat3","Cat2","Cat2","Cat2") year <- c(2010,2011,2012,2013,2014,2015,2016,2017,2018) df <- data.frame(Cat=cat, Year=year) df_result <- df %>% # 先按年份排序,确保时间顺序正确 arrange(Year) %>% # 生成辅助分组ID:类别变化 或 年份不连续时,分组ID+1 mutate(grp = cumsum(Cat != lag(Cat, default = first(Cat)) | Year != lag(Year, default = first(Year)) + 1)) %>% # 按类别和分组ID聚合 group_by(Cat, grp) %>% summarise( Year = min(Year), EYear = max(Year), .groups = "drop" ) %>% # 删除辅助分组列 select(-grp)
运行后得到的df_result和给出的预期输出完全一致。
基础R实现(无需依赖第三方包)
# 构造示例数据 cat <- c("Cat1","Cat1","Cat2","Cat2","Cat2","Cat3","Cat2","Cat2","Cat2") year <- c(2010,2011,2012,2013,2014,2015,2016,2017,2018) df <- data.frame(Cat=cat, Year=year) # 按年份排序 df_sorted <- df[order(df$Year), ] # 生成辅助分组ID grp <- cumsum(c(TRUE, tail(df_sorted$Cat, -1) != head(df_sorted$Cat, -1) | tail(df_sorted$Year, -1) != head(df_sorted$Year, -1) + 1)) # 按分组聚合得到结果 df_result <- do.call(rbind, lapply(split(df_sorted, grp), function(x) { data.frame(Cat = x$Cat[1], Year = min(x$Year), EYear = max(x$Year), row.names = NULL) })) rownames(df_result) <- NULL
内容的提问来源于stack exchange,提问作者user16543787
相关产品推荐
相关产品推荐

