My goal is to compute the intersections of several vectors (sets of identifiers, gene-names to be specific). I start with a list of vectors and run the function below, which loops through 1:n where n is the number of sets and then uses combn to generate all combinations of my sets taken m at a time.
I paste together a name and then reduce by intersection over my sets yielding a named list of character vectors holding the elements in common between each combination of sets.
My question is, of course, is there a better way to accomplish this?
## Compute the intersection of all combinations of the
## elements in the list of vectors l. Might be useful
## for generating Venn/Euler diagrams.
## There might be better ways to do this!
overlap <- function(l) {
results <- list()
# combinations of m elements of list l
for (m in seq(along=l)) {
# generate and iterate through combinations of length m
for (indices in combn(seq(length(l)), m, simplify=FALSE)) {
# make name by concatenating the names of the elements
# of l that we're intersecting
name <- do.call(paste, c(as.list(names(l)[indices]), sep="_"))
# adding the init=l[indices[1]] parameter helps with the case
# where we're only dealing with one set, i==1 and length(indices)==1,
# and we want only unique items in that set.
# Reduce(intersect, list(c(1,2,3,3))) => c(1,2,3,3)
# Reduce(intersect, list(c(1,2,3,3)), init=l[[indices[1]]]) => c(1,2,3)
results[[name]] <- Reduce(intersect, l[indices], init=l[[indices[1]]])
}
}
results
}
overlap( list(foo=c('a','b','c','d','e','e'),
bar=c('a','c','e','f','g'),
bat=c('a','b','c','d','g')))