You need to enable JavaScript to run this app. R语言:按Species分组合并Events/Groups均有匹配的数据框行
优惠活动
大模型
产品
解决方案
定价
更多

R语言:按Species分组合并Events/Groups均有匹配的数据框行

R语言同物种分组下满足双交集条件的行合并实现

核心实现思路为:按物种拆分后,以“两行同时存在Events公共元素、Groups公共元素”作为连接边,构建邻接图后识别连通分量,对每个连通分量内的元素完成去重、排序后逗号拼接,完全匹配需求规则。

可复现代码

首先载入你提供的原始数据,完成基础清洗(转字符串类型、去除分组字段的前置空格):

# 原始数据导入
df <- structure(list(Species = structure(c(3L, 3L, 2L, 2L, 1L, 1L), .Label = c("Dog", 
"Elephant", "Monkey"), class = "factor"), Family = structure(1:6, .Label = c("A", 
"A,B", "B", "C", "K", "L,M,N"), class = "factor"), Events = structure(c(2L, 
3L, 4L, 6L, 1L, 5L), .Label = c("10", "6,7", "6,8,9", "7,8", 
"8,10,9", "9,10"), class = "factor"), Groups = structure(c(1L, 
3L, 2L, 4L, 5L, 6L), .Label = c(" G1,G2", " G6,G7", "G1,G2,G4,G8,G12", 
"G6", "G90", "G90,G91"), class = "factor")), class = "data.frame", row.names = c(NA, 
-6L))

# 基础数据清洗
df[] <- lapply(df, as.character)
df$Groups <- trimws(df$Groups) # 去除原始Groups字段的前置空格

载入依赖包,执行合并逻辑:

library(igraph)
library(dplyr)

final_res <- df %>%
  group_split(Species) %>%
  lapply(function(species_part) {
    # 单条数据直接返回
    if(nrow(species_part) == 1) return(species_part)

    # 拆分每行的Events、Groups为独立元素集合
    event_list <- strsplit(species_part$Events, ",", fixed = TRUE)
    group_list <- strsplit(species_part$Groups, ",", fixed = TRUE)
    row_num <- nrow(species_part)

    # 构建邻接关系:满足双交集条件的两行标记为连通
    adj_matrix <- matrix(FALSE, row_num, row_num)
    for (i in 1:(row_num-1)) {
      for (j in (i+1):row_num) {
        has_event_inter <- length(intersect(event_list[[i]], event_list[[j]])) > 0
        has_group_inter <- length(intersect(group_list[[i]], group_list[[j]])) > 0
        if (has_event_inter & has_group_inter) {
          adj_matrix[i,j] <- adj_matrix[j,i] <- TRUE
        }
      }
    }
    diag(adj_matrix) <- TRUE # 行自身与自身连通

    # 识别连通分量,作为合并分组的唯一标识
    conn_graph <- graph_from_adjacency_matrix(adj_matrix)
    merge_group_id <- components(conn_graph)$membership

    # 按连通组合并元素:去重、排序后逗号拼接
    species_part %>%
      mutate(merge_group = merge_group_id) %>%
      group_by(Species, merge_group) %>%
      summarise(
        Family = paste(sort(unique(unlist(strsplit(Family, ",", fixed=TRUE)))), collapse = ","),
        Events = paste(sort(as.integer(unique(unlist(strsplit(Events, ",", fixed=TRUE))))), collapse = ","),
        Groups = paste(sort(unique(unlist(strsplit(Groups, ",", fixed=TRUE)))), collapse = ","),
        .groups = "drop"
      ) %>%
      select(-merge_group)
  }) %>%
  bind_rows()

输出结果

执行上述代码后得到的结果与你描述的期望输出完全一致:

SpeciesFamilyEventsGroups
DogK,L,M,N8,9,10G90,G91
ElephantB7,8G6,G7
ElephantC9,10G6
MonkeyA,B6,7,8,9G1,G2,G4,G8,G12

细节说明

  • 采用连通分量算法而非简单两两合并,支持传递性关联的合并场景:比如行1与行2符合合并条件、行2与行3符合合并条件时,即使行1与行3无直接公共元素,也会被合并到同一组,避免逻辑漏洞
  • Events列做了数值类型转换后排序,不会出现字符串排序导致的顺序错乱(比如不会把"8,9,10"错误拼接为"8,10,9")
  • 自动过滤原始数据中的无效空格、重复元素,保证拼接结果干净无冗余

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 02:24:04