R tidyverse:两列集合的并集的唯一标识符

问题描述

我有一个产品数据集,其中有两列代表分类。我想基于两个集合的联合获得一个组ID。

在这样的意义上,组ID必须是可传递的:如果观察值1和2的class1相同,而2和3的class2相等,则1,2和3相等。在该示例中,您可以看到传递性在结果中起作用,其中1-4列具有相同的group_id。

任何有关如何做到这一点的技巧将不胜感激=)

# Example
df <- tribble(
  ~id,~class1,~class2,1,"A","L1",2,3,"B",4,"L2",5,"C","L3",6,"D","L4")

# Desired output
result <- tribble(
  ~id,~group_id,"L4",3)

解决方法

df %>%
  mutate(group_id = 1 + cumsum(!(class1 == lag(class1,default = class1[1]) | 
                                 class2 == lag(class2,default = class2[1]))))
# # A tibble: 6 x 4
#      id class1 class2 group_id
#   <dbl> <chr>  <chr>     <dbl>
# 1     1 A      L1            1
# 2     2 A      L1            1
# 3     3 B      L1            1
# 4     4 B      L2            1
# 5     5 C      L3            2
# 6     6 D      L4            3

1+的获取方式与您完全一样,否则,没有前四行的是0,依此类推。这没问题,如果从0开始或从1开始,它们仍然分组相同

,

也许我们可以使用igraph

library(dplyr)
library(igraph)
df %>% 
   select(-id) %>% 
   graph_from_data_frame %>% 
   clusters %>%
   pluck(membership) -> cls
df %>% 
     mutate(group_size = cls[class1])
# A tibble: 6 x 4
#     id class1 class2 group_size
#  <dbl> <chr>  <chr>       <dbl>
#1     1 A      L1              1
#2     2 A      L1              1
#3     3 B      L1              1
#4     4 B      L2              1
#5     5 C      L3              2
#6     6 D      L4              3