0

I am trying to write a function that takes the intersection of however many elements I ask for it. I'm sure that this is probably written in some package, but I am trying to do it myself. I'm new to functions in R. For a given list ll defined as:

ll <- list(a=data.frame(x=c(1,2,3,4,5,6,7)),
           b=data.frame(x=c(1,2,3,4,5,6,7,8,9)),
           c=data.frame(x=c(1,3,4,5,6,7)),
           d=data.frame(x=c(1,2,3,6,7)),
           e=data.frame(x=c(1,2,3,4,5)))

I've written the following function that works properly for returning the intersection of 2 or 3 things, but I can't figure out how to correctly make the last part for (i in 3:length(n)) {.....}. I'm not sure how to make it open ended and keep adding a prior calculated result to the next intersection.

test.intersect <- function(vec,mylist){
  myvec <- unlist(vec)
  n = length(myvec)
  if (n == 1) {
    stop("must have 2 elements to compare")
  }
  inter1_2 <- intersect(mylist[[myvec[1]]], mylist[[myvec[2]]])

  if (n == 2) {return(nrow(inter1_2))} else
  for (i in 3:length(n)){
    return(nrow(intersect(inter1_2,mylist[[myvec[i]]])))
  }
}

The first 3 evaluate correctly, while the last one does not.

> test.intersect(vec = list(1), mylist = ll)
Error in test.intersect(vec = list(1), mylist = ll) : 
  must have 2 elements to compare
> test.intersect(vec = list(1,2), mylist = ll)
[1] 7
> test.intersect(vec = list(1,2,3), mylist = ll)
[1] 6
> test.intersect(vec = list(1,2,3,4), mylist = ll)
[1] 6
Sotos
  • 51,121
  • 6
  • 32
  • 66
akaDrHouse
  • 2,190
  • 2
  • 20
  • 29
  • You are looking for `Reduce`. Try `Reduce(intersect, lapply(ll, unlist))` – Sotos Jun 13 '17 at 17:58
  • [This is the more generic one](https://stackoverflow.com/questions/3695677/how-to-find-common-elements-from-multiple-vectors) – Sotos Jun 13 '17 at 18:04
  • 1
    Thanks @Sotos. With my example, I was able to use your code as follows and it works very well. Thanks again. `length(Reduce(intersect, lapply(ll, unlist)[c(1,2,3,4)]))` – akaDrHouse Jun 13 '17 at 18:05

0 Answers0