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

R语言基于两列序列值为宽表透视分配正确分组ID

问题说明
  • 现有长格式data.frame,每条记录对应一个action的start/end日期:部分action可能仅存在start日期,同一类action可多次触发start、end流程。
  • 需求为将长表转为宽表,单次start对应单独一行,需要给每组start-end配对分配唯一分组ID以完成透视。
  • 此前尝试用rle方法实现,但无法结合两列信息生成正确分组ID,测试代码、当前输出、预期输出如下:
library(tidyverse)
library(data.table)

x <- c("start", "end")
foo <- data.frame(time = c(rep(x, 3), "start", x, "start"), 
           action = rep(letters[1:4], times = c(4,2,3,1)), 
           day = 1:10)

# 尝试用rle生成分组字段,无法得到正确ID
foo %>%
  mutate(rle_time = rleid(time), 
         rle_action = rleid(action))
#>     time action day rle_time rle_action
#> 1  start      a   1        1          1
#> 2    end      a   2        2          1
#> 3  start      a   3        3          1
#> 4    end      a   4        4          1
#> 5  start      b   5        5          2
#> 6    end      b   6        6          2
#> 7  start      c   7        7          3
#> 8  start      c   8        7          3
#> 9    end      c   9        8          3
#> 10 start      d  10        9          4

# 预期输出
data.frame(action = rep(letters[1:4], times = c(2,1,2,1)), 
           start = c(seq(1,7,2),8,10), 
           end = c(seq(2,6,2), NA,9,NA)
           )
#>   action start end
#> 1      a     1   2
#> 2      a     3   4
#> 3      b     5   6
#> 4      c     7  NA
#> 5      c     8   9
#> 6      d    10  NA
实现方法

不需要复杂的rle逻辑,按action分组后,每遇到一次start就将分组计数加1,即可得到正确的配对ID,后续直接透视即可:

foo %>%
  # 按action分组,每个action类别内单独计数
  group_by(action) %>%
  # 累计start出现的次数,作为同类别下的配对ID
  mutate(pair_id = cumsum(time == "start")) %>%
  # 转为宽表
  pivot_wider(id_cols = c(action, pair_id), 
              names_from = time, 
              values_from = day) %>%
  # 移除辅助ID列,整理输出
  ungroup() %>%
  select(-pair_id)

运行结果和预期完全一致:

# A tibble: 6 × 3
  action start   end
  <chr>  <int> <int>
1 a          1     2
2 a          3     4
3 b          5     6
4 c          7    NA
5 c          8     9
6 d         10    NA

逻辑说明:每个end必然归属于它之前最近的一个未闭合的start,按action分组后累计start的出现次数,正好可以给每个start和后续对应的end分配相同的ID;连续出现多个start时,每个start会单独生成一个ID,靠前的start如果没有对应的end,透视后end字段自动为NA,完全匹配需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 21:27:38