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

如何在R data.table中为某列连续相同值分组分配递增索引

问题描述

我有如下data.table:

example <- data.table(time = 1:30,
                  A = c(rep("a", 5), rep("b", 5), rep("a", 5), 
                        rep("b", 2), rep("a", 8), rep("b", 3), rep("a", 2)))

需要基于A列分配递增索引,得到如下输出:

time A B
  1  a 1
  2  a 1
  3  a 1
  4  a 1
  5  a 1
  6  b 1
  7  b 1
  8  b 1
  9  b 1
 10  b 1
 11  a 2
 12  a 2
 13  a 2
 14  a 2
 15  a 2
 16  b 2
 17  b 2
 18  a 3
 19  a 3
 20  a 3
 21  a 3
 22  a 3
 23  a 3
 24  a 3
 25  a 3
 26  b 3
 27  b 3
 28  b 3
 29  a 4
 30  a 4

希望得到data.table方案或其他可行解决办法。


解决方案

data.table 实现方案

通过检测A列的切换点(从非a切换到a),对切换点做累积和即可生成目标索引列B:

library(data.table)

example <- data.table(time = 1:30,
                  A = c(rep("a", 5), rep("b", 5), rep("a", 5), 
                        rep("b", 2), rep("a", 8), rep("b", 3), rep("a", 2)))

# 生成索引列B
example[, B := cumsum(c(TRUE, A[-1] != A[-length(A)] & A[-1] == "a"))]

逻辑说明

  • A[-1] != A[-length(A)]:判断当前行与前一行的A值是否不同
  • & A[-1] == "a":仅筛选从非a切换到a的情况
  • c(TRUE, ...):第一行默认属于第一个索引块,开头补TRUE
  • cumsum():对切换标记做累积和,得到递增的索引值

验证结果

运行代码后,example的输出与需求完全一致:

> example
    time A B
 1:    1 a 1
 2:    2 a 1
 3:    3 a 1
 4:    4 a 1
 5:    5 a 1
 6:    6 b 1
 7:    7 b 1
 8:    8 b 1
 9:    9 b 1
10:   10 b 1
11:   11 a 2
12:   12 a 2
13:   13 a 2
14:   14 a 2
15:   15 a 2
16:   16 b 2
17:   17 b 2
18:   18 a 3
19:   19 a 3
20:   20 a 3
21:   21 a 3
22:   22 a 3
23:   23 a 3
24:   24 a 3
25:   25 a 3
26:   26 b 3
27:   27 b 3
28:   28 b 3
29:   29 a 4
30:   30 a 4

其他可行方案(dplyr)

若习惯使用dplyr,可通过以下代码实现:

library(dplyr)

example %>%
  mutate(
    switch_flag = case_when(
      row_number() == 1 ~ TRUE,
      A != lag(A) & A == "a" ~ TRUE,
      TRUE ~ FALSE
    ),
    B = cumsum(switch_flag)
  ) %>%
  select(-switch_flag)

内容的提问来源于stack exchange,提问作者s.cerioli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:17:13