Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping columns based on pairwise equality

Tags:

r

combinations

I have a matrix called equalityMatrix

> equalityMatrix
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18]
[1,]   29   29   29   29   55   55   55   55  101   101   101   111   111   115   134   134   134   151
[2,]  101  111  115  316  134  151  235  319  111   115   316   115   316   316   151   235   319   235
     [,19] [,20]
[1,]   151   235
[2,]   319   319

(Make yours:)

structure(c(29L, 101L, 29L, 111L, 29L, 115L, 29L, 316L, 55L, 
134L, 55L, 151L, 55L, 235L, 55L, 319L, 101L, 111L, 101L, 115L, 
101L, 316L, 111L, 115L, 111L, 316L, 115L, 316L, 134L, 151L, 134L, 
235L, 134L, 319L, 151L, 235L, 151L, 319L, 235L, 319L), .Dim = c(2L, 
20L))

This signifies that element 29 equals elements 101, 111, 115, and 316; that element 55 equals elements 134, 151, 235, and 319; and so on and so forth.

How do I efficiently obtain a list of equal elements like below?

[[1]]
[1] 29 101 111 115 316

[[2]]
[1] 55 134 151 235 319

I'll ultimately use the output of this command to create a mapping. These values are essentially indexes of elements that belong to the same group.

like image 969
jackStinger Avatar asked Dec 21 '25 13:12

jackStinger


2 Answers

One way to think of this would be as a graph, where each number is a node in the graph and two numbers co-occurring in a column mean the vertices associated with those two numbers share an edge in the graph. For your example, we could use the igraph package to create a graph with your data:

library(igraph)
g <- graph.data.frame(t(equalityMatrix))
plot(g)

enter image description here

The components of the graph will be the numbers that are equal:

split(as.numeric(V(g)$name), components(g)$membership)
# $`1`
# [1]  29 101 111 115 316
# 
# $`2`
# [1]  55 134 151 235 319
like image 118
josliber Avatar answered Dec 24 '25 02:12

josliber


Something like this:

library(dplyr)

equalityMatrix %>%
  t %>%
  as.data.frame %>%
  setNames(c("group", "value")) %>%
  group_by(group) %>%
  summarize(value = list(value))
like image 25
bramtayl Avatar answered Dec 24 '25 02:12

bramtayl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!