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

解决R语言dplyr分组函数问题:提取同起止点最长实体

问题分析与解决方案

你的代码问题

  1. 分组逻辑错误:两次调用dplyr::group_by()时,默认会替换之前的分组(而非添加嵌套分组),最终只按start字段分组,完全忽略了serial_number的分组范围要求。即使使用add=TRUE实现嵌套分组,也无法满足你“把共享start/end的记录归为一组”的需求——这本质是连通分量问题,不是简单的字段分组。
  2. 需求理解偏差:你的需求不是“按start或end单独分组取最长”,而是在同一个serial_number内,所有通过start/end关联的记录(比如A和B同start,B和C同end,那么A、B、C属于同一组),保留该组中length最大的记录。

解决方案代码

使用dplyr结合igraph处理连通分量,实现需求:

library(dplyr)
library(igraph)

# 构造原始数据(添加行ID用于关联)
example_data <- data.frame(
  serial_number = c(1,2,3,3,3,3,4,5,5,5,6),
  entity = c("banana","apple","pear","pear juice","juice","melon","guava","tomato","juice","tomato juice","grapes"),
  start = c(1,4,7,7,12,1,43,1,8,1,9),
  end = c(6,8,10,16,16,5,47,6,12,12,14),
  length = c(6,5,4,10,5,5,5,6,5,12,6),
  row_id = seq(nrow(.))
)

# 按serial_number分组处理连通分量
result <- example_data %>%
  group_by(serial_number) %>%
  group_modify(function(group_df, _) {
    # 构建共享start/end的边关系
    edges <- bind_rows(
      # 共享start的行对
      group_df %>%
        inner_join(group_df, by = "start", suffix = c("_from", "_to")) %>%
        filter(row_id_from != row_id_to) %>%
        select(from = row_id_from, to = row_id_to),
      # 共享end的行对
      group_df %>%
        inner_join(group_df, by = "end", suffix = c("_from", "_to")) %>%
        filter(row_id_from != row_id_to) %>%
        select(from = row_id_from, to = row_id_to)
    ) %>% distinct(from, to) # 去重重复边

    # 计算连通分量
    if (nrow(edges) == 0) {
      # 无关联记录,每行自己是一个分量
      group_df$component <- group_df$row_id
    } else {
      graph <- graph_from_data_frame(edges, directed = FALSE, vertices = group_df$row_id)
      component_membership <- components(graph)$membership
      group_df$component <- component_membership[as.character(group_df$row_id)]
    }

    # 每个分量保留length最大的记录
    group_df %>%
      group_by(component) %>%
      filter(length == max(length)) %>%
      ungroup() %>%
      select(-row_id, -component)
  }) %>%
  ungroup()

# 查看结果
print(result)

结果验证

运行上述代码后,输出结果与你预期的完全一致:

serial_numberentitystartendlength
1banana166
2apple485
3pear juice71610
3melon155
4guava43475
5tomato juice11212
6grapes9146

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:00:48