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

在R中对分组数据按列排序并生成基于值变化的连续行号

R语言分组生成连续行号需求解决方案

问题背景

现有一份按id、Date、value排序的data.frame数据,需在同一id分组内,对比相邻行的value字段:若当前行value与上一行不同,则Row_Number加1;若相同则保持不变。

原始数据示例

id   value      Date 
 ---- --------   -----------    
   1    A        2018-03-07     
   1    A        2018-03-26
   1    B        2018-04-01     
   1    B        2018-04-15
   1    C        2018-05-07     
   1    A        2018-06-26

   2    A        2018-03-07     
   2    A        2018-03-26
   2    B        2018-04-01     
   2    C        2018-04-15
   2    C        2018-05-07     
   2    B        2018-06-26

生成原始数据的代码

df <- as.data.frame(cbind( 
                      id = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2), 
                   value = c("A", "A", "B", "B", "C", "A", "A", "A", "B", "C", "C", "B"),
       
                   Date = c("2018-03-27", "2018-03-26", "2018-04-01", "2018-04-15", "2018-05-07", "2018-06-26","2018-03-27", "2018-03-26", "2018-04-01", "2018-04-15", "2018-05-07", "2018-06-26")
                      ))

期望输出结果

id     value      Date          Row_Number
 ---- --------   -----------   ----------- 
   1    A        2018-03-07     1
   1    A        2018-03-26     1
   1    B        2018-04-01     2
   1    B        2018-04-15     2
   1    C        2018-05-07     3
   1    A        2018-06-26     4

   2    A        2018-03-07     1
   2    A        2018-03-26     1
   2    B        2018-04-01     2
   2    C        2018-04-15     3
   2    C        2018-05-07     3
   2    B        2018-06-26     4

实现方案

方案一:使用dplyr包(推荐)

借助dplyr的分组和窗口函数可以简洁实现需求,步骤包括日期类型转换、排序、分组对比相邻值、累加变化标记:

# 加载dplyr包,若未安装先执行 install.packages("dplyr")
library(dplyr)

df_processed <- df %>%
  # 将字符型Date转换为日期类型
  mutate(Date = as.Date(Date)) %>%
  # 确保数据按id和Date排序
  arrange(id, Date) %>%
  # 按id分组处理
  group_by(id) %>%
  # 生成变化标记:首行标记为1,后续行若value与上一行不同则标记为1,否则为0
  mutate(value_change = ifelse(row_number() == 1, 1, as.integer(value != lag(value)))) %>%
  # 累加变化标记得到Row_Number
  mutate(Row_Number = cumsum(value_change)) %>%
  # 取消分组
  ungroup()

# 查看处理后的数据
print(df_processed)

方案二:基础R实现

如果不想依赖第三方包,可通过循环分组处理:

# 转换Date为日期类型
df$Date <- as.Date(df$Date)
# 按id和Date排序数据
df <- df[order(df$id, df$Date), ]

# 初始化Row_Number列
df$Row_Number <- 1

# 遍历每个id分组计算行号
for (current_id in unique(df$id)) {
  # 筛选当前id的行
  group_indices <- df$id == current_id
  # 获取当前分组的value序列
  group_values <- df$value[group_indices]
  
  # 生成变化标记:首行为1,后续行对比上一行是否不同
  change_flags <- c(1, as.integer(diff(as.factor(group_values)) != 0))
  # 累加标记得到Row_Number
  df$Row_Number[group_indices] <- cumsum(change_flags)
}

# 查看结果
print(df)

内容的提问来源于stack exchange,提问作者Bernice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 21:10:37