[R] intersect more than two sets

Peter Dalgaard p.dalgaard at biostat.ku.dk
Tue Apr 24 22:03:20 CEST 2007


hadley wickham wrote:
> On 4/24/07, Weiwei Shi <helprhelp at gmail.com> wrote:
>   
>> assume t2 is a list of size 11 and each element is a vector of characters.
>>
>> the following codes can get what I wanted but I assume there might be
>> a one-line code for that:
>>
>> t3 <- t2[[1]]
>> for ( i in 2:11){
>>         t3 <- intersect(t2[[i]], t3)
>> }
>>
>> or there is no such "apply"?
>>     
>
> The operation you want is called a fold
> (http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29), and
> if it was available in R, you'd be able to do:
>
> fold(t2, intersect)
>
> Unfortunately, it's not, but you could implement it as follows:
>
> fold <- function(x, fun) {
> 	if (length(x) == 1) return(fun(x))
> 	
> 	accumulator <- fun(x[[1]], x[[2]])
> 	if (length(x) == 2) return(accumulator)
>
> 	for(i in 3:length(x)) {
> 		accumulator <- fun(accumulator, x[[i]])
> 	}
> 	accumulator
> }
>
> a <- list(c(1,3,5), c(1,3), c(1, 2, 5, 6))
> fold(a, intersect)
>
>   

It's come up before. Gabor G posted this rather more succinct version:

 > Fold <- function(f, x, L) (for(e in L) x <- f(x, e))
 > Fold(intersect,a[[1]],a[-1])
[1] 1

or maybe prettier:

 > (E <- Fold(union, NULL, a))
[1] 1 3 5 2 6
 > Fold(intersect, E, a)
[1] 1


> Which is just a trivial generalisation of your code above
>



More information about the R-help mailing list