You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:45:02