[R] intersect more than two sets

John Fox jfox at mcmaster.ca
Tue Apr 24 23:41:11 CEST 2007


Dear Peter, Hadley, et al.,

Just to bring it back around, here's a recursive Fold():

> a <- letters[1:4]
> b <- letters[2:5]
> c <- letters[3:6]
> d <- letters[4:7]
> e <- letters[5:8]

> Fold <- function(f, x, y, ...){
+     if (missing(...)) f(x, y)
+     else f(x, Fold(f, y, ...))
+ }

> Fold(intersect, a, b)
[1] "b" "c" "d"
> Fold(intersect, a, b, c)
[1] "c" "d"
> Fold(intersect, a, b, c, d)
[1] "d"
> Fold(intersect, a, b, c, d, e)
character(0)
> 
> do.call(Fold, list(intersect, a, b, c, d))
[1] "d"

Regards,
 John

--------------------------------
John Fox, Professor
Department of Sociology
McMaster University
Hamilton, Ontario
Canada L8S 4M4
905-525-9140x23604
http://socserv.mcmaster.ca/jfox 
-------------------------------- 

> -----Original Message-----
> From: r-help-bounces at stat.math.ethz.ch 
> [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Peter Dalgaard
> Sent: Tuesday, April 24, 2007 4:03 PM
> To: hadley wickham
> Cc: R Help; Weiwei Shi
> Subject: Re: [R] intersect more than two sets
> 
> 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
> >
> 
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide 
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>



More information about the R-help mailing list