【问题标题】:dplyr group by union of multiple columnsdplyr 通过多列的并集分组
【发布时间】:2019-05-03 04:51:00
【问题描述】:

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 年 5 月 3 日创建

【问题讨论】:

  • 我不确定我是否理解预期的输出。第 2 行属于第 2 组,因为它与第 1 组中的 anything 不匹配,然后第 3 行也进入第 2 组,因为它与第 2 组有 1 个匹配项?第 7 行呢?
  • 您不能唯一标识这样一个组,因为它们不会相互排斥。这似乎是一个集群问题。
  • 第 7 行的 @Marius id1id2 与第 2 行的匹配,因此 ii 预计属于同一组。
  • @Rohit 对于这个特殊的虚拟示例,它们是专有的。这确实是一种聚类,我同意这一点。

标签: r dplyr


【解决方案1】:

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

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

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

【讨论】:

  • 我希望有一个dplyr 解决方案,但这也很好。谢谢。
猜你喜欢
  • 2017-06-12
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 2021-01-04
相关资源
最近更新 更多