dplyr按多个列进行分组

时间:2019-05-03 04:51:01

标签: r dplyr

dplyr可以按多个列(例如ID列)分组,但是要考虑它们的交集。因此,这些ID列的所有可用组合都被视为考虑不同组的因素。

我正在寻找多列的并集,即如果两行至少由ID列之一匹配,我希望它们属于同一组。

this thread中,有一个使用igraph包的解决方案。当我有两个以上的ID列时,我无法一概而论,因为graph_from_data_frame的文档中指出:

  

d

     

在前两列中包含符号边缘列表的数据帧。其他列被视为边缘属性。

这是一个例子:

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

input_df <- tibble(id1 = c(1, 2, 3, 4, 5, 2, 2, 3, 4 ,1),
                   id2 = c(1, 2, 3, 1, 2, 3, 3, 2, 4, 1),
                   id3 = c(1, 2, 2, 1, 2, 3, 4, 2, 5, 5))
input_df
#> # A tibble: 10 x 3
#>      id1   id2   id3
#>    <dbl> <dbl> <dbl>
#>  1     1     1     1
#>  2     2     2     2
#>  3     3     3     2
#>  4     4     1     1
#>  5     5     2     2
#>  6     2     3     3
#>  7     2     3     4
#>  8     3     2     2
#>  9     4     4     5
#> 10     1     1     5

grouped_df <- input_df %>%
  group_by(id1, id2, id3) %>%
  mutate(id = group_indices())
grouped_df
#> # A tibble: 10 x 4
#> # Groups:   id1, id2, id3 [10]
#>      id1   id2   id3    id
#>    <dbl> <dbl> <dbl> <int>
#>  1     1     1     1     1
#>  2     2     2     2     3
#>  3     3     3     2     7
#>  4     4     1     1     8
#>  5     5     2     2    10
#>  6     2     3     3     4
#>  7     2     3     4     5
#>  8     3     2     2     6
#>  9     4     4     5     9
#> 10     1     1     5     2

expected_df <- bind_cols(input_df,
                         id = c(1, 2, 2, 1, 2, 2, 2, 2, 1, 1))
expected_df
#> # A tibble: 10 x 4
#>      id1   id2   id3    id
#>    <dbl> <dbl> <dbl> <dbl>
#>  1     1     1     1     1
#>  2     2     2     2     2
#>  3     3     3     2     2
#>  4     4     1     1     1
#>  5     5     2     2     2
#>  6     2     3     3     2
#>  7     2     3     4     2
#>  8     3     2     2     2
#>  9     4     4     5     1
#> 10     1     1     5     1

reprex package(v0.2.1)于2019-05-03创建

1 个答案:

答案 0 :(得分:0)

通过使用igraph创建邻接矩阵,您可以应用rdist::pdist方法了:

library(rdist)
library(igraph)

matches = rdist::pdist(input_df, metric = function(x, y) { any(x == y) })
g = graph_from_adjacency_matrix(matches)
input_df$g = clusters(g)$membership

由于需要使用自定义函数计算成对距离,因此在处理较大数据时可能会变慢。