Sulawesi
Sulawesi

Reputation: 565

How to generate a matrix of circular-splits?

I have an ordering of populations along a circle. Let Z be an ordering of all my 5 populations named "A".. "E".

Z = c("A","B","C","D","E")

A split is one possibility to seperate all populations into two sets, where each set contain at least one population. THe splits that put D on one side and EABC on the other side is called Splits D|EABC. I don't want to make any different between D|EABC and EABC|D. The split D|EABC is represented by the green line on the figure below. All the lines below represent all the existing splits.

Circular Splits of 5 populations

My goal is to generate all the splits possible and to build up a matrix that tells me whether a given pair of population is found in the same set of in the opposite set when a given split occurs. For example split AB | DCE put population A and C on two different sets but does not put A and B in two different sets. From the vector Z, I aim to build the following kind of matrix, where a 1 indicates that the two populations are in the same set and a 0 indicate that the two population are different sets

Splits matrix (not complete)

How can I do that in R?

Upvotes: 1

Views: 71

Answers (1)

IRTFM
IRTFM

Reputation: 263301

These are all the ten splits with their complements:

first <- sapply(1:10, function(n) 
          LETTERS[1:5][combn(1:5,2)[1,n]:(combn(1:5,2)[2,n]-.1) ] )
comps <- sapply(first , function(f) setdiff( LETTERS[1:5] , f)  )

These are the ten pairings:

> pairings <- sapply(1:10, function(n) LETTERS[1:5][c(combn(1:5,2)[1,n], combn(1:5,2)[2,n]) ] )
> pairings
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "a"  "a"  "a"  "a"  "b"  "b"  "b"  "c"  "c"  "d"  
[2,] "b"  "c"  "d"  "e"  "c"  "d"  "e"  "d"  "e"  "e"  

This should deliver the matrix:

outer(1:10, 1:10 , FUN= Vectorize( function(x,y){   # Either:
            (pairings[1,x] %in% first[[y]] & pairings[2,x] %in% comps[[y]] ) |  # Or
            (pairings[2,x] %in% first[[y]] & pairings[1,x] %in% comps[[y]] ) }))

       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
 [1,]  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE
 [2,]  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE
 [3,]  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE
 [4,]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
 [5,] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE
 [6,] FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE
 [7,] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
 [8,] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [9,] FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE
[10,] FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE

If you need to matrix an R logical matrix into 1/0 just add 0 to it.

Upvotes: 1

Related Questions