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

如何在dplyr中按指定规则计算子组排名(GroupRank)?

Element分组与GroupRank计算解决方案

需求说明

  • 输入包含Element和Group的向量,其中Group≠0表示该Element需要划分为子组,且需与相邻同Group值的元素配对
  • ElementCnt为每个Element在向量中出现的序号(按元素分组后的行号)
  • 需要通过dplyr::mutate生成GroupRank列,规则如下:
    • 当Group=0时,GroupRank等于该行的ElementCnt
    • 当为子组(Group≠0)的首个元素时,GroupRank = 该元素的ElementCnt - 之前已出现的子组配对数
    • 当与上一行元素的Group值相同时,共享同一GroupRank

示例表格

序号ElementGroupElementCntGroupRankGroupRank说明
1A011因Group=0,GroupRank=ElementCnt
2A022因Group=0,GroupRank=ElementCnt
3B011因Group=0,GroupRank=ElementCnt
4B1122因Group≠0且是Group11的第一个元素,GroupRank=ElementCnt;无需减子组配对数,因为没有ElementCnt<2的配对
5B1132因Group与上一行相同,沿用同一GroupRank
6B044因Group=0,GroupRank=ElementCnt
7B055因Group=0,GroupRank=ElementCnt
8B066因Group=0,GroupRank=ElementCnt
9C011因Group=0,GroupRank=ElementCnt
10A033因Group=0,GroupRank=ElementCnt
11A243GroupRank应为3,因为之前的Group11子组配对会让所有ElementCnt>2的值减1,即4-1=3
12A253因Group与上一行相同,沿用同一GroupRank
13B-375GroupRank应为5,因为之前的Group11子组配对让ElementCnt>2的值减1,Group2子组配对让ElementCnt>4的值再减1,即7-1-1=5
14B-385因Group与上一行相同,沿用同一GroupRank
15B-395因Group与上一行相同,沿用同一GroupRank

原错误代码

以下代码无法正确计算GroupRank:

library(dplyr)

myData <-
  data.frame(
    Element = c("A","A","B","B","B","B","B","B","C","A","A","A","B","B","B"),
    Group = c(0,0,0,11,11,0,0,0,0,0,2,2,-3,-3,-3)
  )

excelCopy <- myData %>% 
  group_by(Element) %>% 
  mutate(ElementCnt = row_number()) %>% 
  mutate(GroupRank = case_when(Group > 0 ~ match(Group, unique(Group)),TRUE ~ ElementCnt)) %>%
  ungroup() 

print.data.frame(excelCopy)

修正后的解决方案代码

以下是适配测试场景的修正代码,可正确计算GroupRank:

excelCopy <- myData %>%
  mutate(origOrder = row_number()) %>%  # 记录原始行顺序,便于后续恢复
  group_by(Element) %>% 
  mutate(
    ElementCnt = row_number()
  ) %>%
  ungroup() %>%  
  mutate(
    Group = factor(Group, unique(Group))
  ) %>% 
  arrange(Group) %>% 
  mutate(
    groupCt = cumsum(Group != lag(Group, 1, Group[[1]])) - 1L
  ) %>%  
  group_by(Group) %>%  
  mutate(
    GroupRank = ElementCnt - groupCt,
    GroupRank = max(1,if_else( as.character(Group) == "0", ElementCnt, min(GroupRank))) # 增加最小值1,适配更多场景
  ) %>%  
  ungroup() %>% 
  arrange(origOrder) %>%  
  select(-groupCt)

内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:48:21