Felix T.
Felix T.

Reputation: 530

Finding network links from cluster information

I have network data that looks like this:

data <- data.frame(id = as.character(1:20),
                   cluster = sample(c("a", "b", "c"), 20, replace = T)) 
head(data)

# id cluster
# 1       b
# 2       b
# 3       c
# 4       a
# 5       c
# 6       a
# 7       a

In the past, I've successfully gotten cluster data from links, but not the other way around. I tried using the igraph package for network analysis but couldn't find a function that gave me a satisfactory result, and I didn't want to rely on a loop since they're inefficient and I in general try to stay away from them.

Expected Result

I'm wondering if there's an efficient way to create a new data.frame with all possible "links" within a cluster, so that I end up with a data.frame that looks like:

id1 id2 cluster
4   6       a
7   4       a
7   6       a
1   2       b
3   5       c

Upvotes: 3

Views: 51

Answers (1)

M--
M--

Reputation: 28955

You can do this in :

set.seed(123)
data <- data.frame(id = as.character(1:20),
                   cluster = sample(c("a", "b", "c"), 20, replace = T))

library(data.table)
setDT(data)[, id:=as.character(id)][, t(combn(id, 2, FUN = list)), by = cluster]
#>     cluster V1 V2        #>     cluster V1 V2        #>     cluster V1 V2    
#>  1:       a  1 17        #> 21:       c 12  8        #> 41:       c  5  8    
#>  2:       a  1  7        #> 22:       c 12 13        #> 42:       c  5 13    
#>  3:       a  1  9        #> 23:       c 15 16        #> 43:       c  8 13    
#>  4:       a  1 10        #> 24:       c 15 19        #> 44:       b 14 18    
#>  5:       a  1 11        #> 25:       c 15  3        #> 45:       b 14 20    
#>  6:       a 17  7        #> 26:       c 15  5        #> 46:       b 14  2    
#>  7:       a 17  9        #> 27:       c 15  8        #> 47:       b 14  4    
#>  8:       a 17 10        #> 28:       c 15 13        #> 48:       b 14  6    
#>  9:       a 17 11        #> 29:       c 16 19        #> 49:       b 18 20    
#> 10:       a  7  9        #> 30:       c 16  3        #> 50:       b 18  2    
#> 11:       a  7 10        #> 31:       c 16  5        #> 51:       b 18  4    
#> 12:       a  7 11        #> 32:       c 16  8        #> 52:       b 18  6    
#> 13:       a  9 10        #> 33:       c 16 13        #> 53:       b 20  2    
#> 14:       a  9 11        #> 34:       c 19  3        #> 54:       b 20  4    
#> 15:       a 10 11        #> 35:       c 19  5        #> 55:       b 20  6    
#> 16:       c 12 15        #> 36:       c 19  8        #> 56:       b  2  4    
#> 17:       c 12 16        #> 37:       c 19 13        #> 57:       b  2  6    
#> 18:       c 12 19        #> 38:       c  3  5        #> 58:       b  4  6    
#> 19:       c 12  3        #> 39:       c  3  8            
#> 20:       c 12  5        #> 40:       c  3 13            

or in :

set.seed(123)
data <- data.frame(id = as.character(1:20),
                   cluster = sample(c("a", "b", "c"), 20, replace = T))

library(dplyr)
data %>% group_by(cluster) %>% mutate(id=as.character(id)) %>% 
         do(data.frame(t(combn(.$id, 2))))
#> # A tibble: 58 x 3
#> # Groups:   cluster [3]
#>    cluster    X1    X2
#>    <fct>   <dbl> <dbl>
#>  1 a           1    17
#>  2 a           1     7
#>  3 a           1     9
#>  4 a           1    10
#>  5 a           1    11
#>  6 a          17     7
#>  7 a          17     9
#>  8 a          17    10
#>  9 a          17    11
#> 10 a           7     9
#> # ... with 48 more rows

Created on 2019-05-16 by the reprex package (v0.2.1)

Upvotes: 3

Related Questions