brandonEm
brandonEm

Reputation: 316

Finding all possible combinations of vector intersections?

I have a set of four vectors that look like this:

[1] PRI2CO       HEISCO       PRI2CO       DIALGU       DIALGU       ALSEBL      
Levels: ALSEBL       DIALGU       HEISCO       PRI2CO  

[1] PRI2CO       TET2PA       ALSEBL       PRI2CO       ALSEBL       TET2PA      
[7] HEISCO       TET2PA      
Levels: ALSEBL       HEISCO       PRI2CO       TET2PA

I would like to generate a vector that contains all values that match between every possible combination of the four vectors. For the two above, it would contain ALESBL, HEISCO, and PRI2CO. I've been doing every combination by hand so far but its tedious and I figure there has to be a better way. I tried writing a loop for it but I'm pretty new to R and it hasn't worked yet. Here's what I've been doing:

trees.species.P234<-intersect(intersect(trees.species.P2,trees.species.P3),trees.species.P4)
> trees.species.P234
[1] "PRI2CO      " "ALSEBL      "

I was thinking a for loop that involved a factorial might do it, but I can't get it to work.

Upvotes: 1

Views: 1574

Answers (3)

thelatemail
thelatemail

Reputation: 93813

Here you go, using the same vectors as proposed by gadzooks:

v1 <- c("PRI2CO","HEISCO","PRI2CO","DIALGU","DIALGU","ALSEBL")
v2 <- c("PRI2CO", "TET2PA","ALSEBL","PRI2CO","ALSEBL","TET2PA","HEISCO","TET2PA")
v3 <- c("PRI2CO","HEISCO","PRI2CO","DIALGU","DIALGU","ALSEBL")
v4 <- c("PRI2CO", "TET2PA","ALSEBL","PRI2CO","ALSEBL","TET2PA","HEISCO","TET2PA")

veclist <- list(v1,v2,v3,v4)
combos <- Reduce(c,lapply(2:length(veclist), 
            function(x) combn(1:length(veclist),x,simplify=FALSE) ))

lapply(combos, function(x) Reduce(intersect,veclist[x]) )

#[[1]]
#[1] "PRI2CO" "HEISCO" "ALSEBL"
# 
#[[2]]
#[1] "PRI2CO" "HEISCO" "DIALGU" "ALSEBL"
#
#[[3]]
#[1] "PRI2CO" "HEISCO" "ALSEBL"
#etc etc

Upvotes: 1

tom.purucker
tom.purucker

Reputation: 71

v1 <- c("PRI2CO","HEISCO","PRI2CO","DIALGU","DIALGU","ALSEBL")
v2 <- c("PRI2CO", "TET2PA","ALSEBL","PRI2CO","ALSEBL","TET2PA","HEISCO","TET2PA")
v3 <- c("PRI2CO","HEISCO","PRI2CO","DIALGU","DIALGU","ALSEBL")
v4 <- c("PRI2CO", "TET2PA","ALSEBL","PRI2CO","ALSEBL","TET2PA","HEISCO","TET2PA")

vall <- unique(c(v1,v2,v3,v4))
for(x in vall){
   if((x %in% v1)&(x %in% v2)&(x %in% v3)&(x %in% v4)){
   print(x)}
}

Upvotes: 0

Koundy
Koundy

Reputation: 5503

First you have to list all the combinations. For that use combn function.

> combn(1:4,2)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1    1    2    2    3
[2,]    2    3    4    3    4    4

Now we can use the apply function to find intersection between your vectors. But before that lets create a list of vectors. For easy reproducibility i created this list.

c <- combn(1:4,2)
l <- list(c("a","b"),c("b","c"),c("c","d"),c("d","e"))
Result <- apply(c,2,function(x){intersect(l[[x[1]]],l[[x[2]]])})

This result will be a list if you want it as vector you can use do.call

do.call("c",Result)
[1] "b" "c" "d"

For unique components

unique(do.call("c",Result))

This can be used for large lists as well.

Upvotes: 0

Related Questions