finding common elements in a list

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

finding common elements in a list

Andy Bunn
Suppose I have a list where I want to extract only the elements that occur
in every component. For instance in the list foo I want to know that the
numbers 2 and 3 occur in every component. The solution I have seems
unnecessarily clunky. TIA, Andy

    foo <- list(x = 1:10, y=2:11, z=1:3)
    bar <-unlist(foo)
    bartab <- table(bar)
    as.numeric(names(bartab)[bartab==length(foo)])

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Reply | Threaded
Open this post in threaded view
|

Re: finding common elements in a list

Patrick Burns
Here is one solution:

 > all(unlist(lapply(foo, function(x) c(2,3) %in% x)))
[1] TRUE

This doesn't have the restriction of assuming that the components
of the list have unique elements, as the original solution does.

Patrick Burns
[hidden email]
+44 (0)20 8525 0696
http://www.burns-stat.com
(home of S Poetry and "A Guide for the Unwilling S User")

Andy Bunn wrote:

>Suppose I have a list where I want to extract only the elements that occur
>in every component. For instance in the list foo I want to know that the
>numbers 2 and 3 occur in every component. The solution I have seems
>unnecessarily clunky. TIA, Andy
>
>    foo <- list(x = 1:10, y=2:11, z=1:3)
>    bar <-unlist(foo)
>    bartab <- table(bar)
>    as.numeric(names(bartab)[bartab==length(foo)])
>
> [[alternative HTML version deleted]]
>
>______________________________________________
>[hidden email] mailing list
>https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>
>
>  
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Reply | Threaded
Open this post in threaded view
|

Re: finding common elements in a list

Bert Gunter
The original post is ambiguous: do you want to find the intersection or do
you want to find whether a prespecified set is in the intersection? Patrick
provided you an answer to the latter while you provided an answer to the
former. Actually, I thought using table as you did (mod the need for no
replicates) was clever. A more direct but I think considerably slower
approach would be to use intersect() in a loop:

inall<-intersect(foo[[1]],foo[[,2]])
for(i in seq(3, to=length(foo))inall<-intersect(inall,foo[[i]])

I suspect you already thought of this and rejected it. Other than
transparency, I think the only advantage it has is that it will work for
something other than lists of numerics, e.g. it will work for lists of
factors, which the table() solution would not.

-- Bert

-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Patrick Burns
Sent: Friday, April 07, 2006 12:04 PM
To: Andy Bunn
Cc: R-Help
Subject: Re: [R] finding common elements in a list

Here is one solution:

 > all(unlist(lapply(foo, function(x) c(2,3) %in% x)))
[1] TRUE

This doesn't have the restriction of assuming that the components
of the list have unique elements, as the original solution does.

Patrick Burns
[hidden email]
+44 (0)20 8525 0696
http://www.burns-stat.com
(home of S Poetry and "A Guide for the Unwilling S User")

Andy Bunn wrote:

>Suppose I have a list where I want to extract only the elements that occur
>in every component. For instance in the list foo I want to know that the
>numbers 2 and 3 occur in every component. The solution I have seems
>unnecessarily clunky. TIA, Andy
>
>    foo <- list(x = 1:10, y=2:11, z=1:3)
>    bar <-unlist(foo)
>    bartab <- table(bar)
>    as.numeric(names(bartab)[bartab==length(foo)])
>
> [[alternative HTML version deleted]]
>
>______________________________________________
>[hidden email] mailing list
>https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide!
http://www.R-project.org/posting-guide.html
>
>
>  
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide!
http://www.R-project.org/posting-guide.html

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Reply | Threaded
Open this post in threaded view
|

Re: finding common elements in a list

Andy Bunn-2
In reply to this post by Andy Bunn
> The original post is ambiguous: do you want to find the intersection or do
> you want to find whether a prespecified set is in the
> intersection? Patrick
> provided you an answer to the latter while you provided an answer to the
> former. Actually, I thought using table as you did (mod the need for no
> replicates) was clever. A more direct but I think considerably slower
> approach would be to use intersect() in a loop:
>
> inall<-intersect(foo[[1]],foo[[,2]])
> for(i in seq(3, to=length(foo))inall<-intersect(inall,foo[[i]])
>
> I suspect you already thought of this and rejected it. Other than
> transparency, I think the only advantage it has is that it will work for
> something other than lists of numerics, e.g. it will work for lists of
> factors, which the table() solution would not.


Indeed, the first post was ambiguous. I was after the type of solution that I posted: the intersection rather than a prespecified set. Given that, I suppose my use of table is satisfactory.

Thanks Patrick and Bert.

-Andy

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Reply | Threaded
Open this post in threaded view
|

Re: finding common elements in a list

Gabor Grothendieck
I guess I am coming a bit late to this but here is a one-line zoo solution.
The lapply creates a zoo object from each foo component with the constant
value 1 and the contents as the times of that object.    Merging the objects
together using cbind gives columns of 1s and NAs and removing the NAs
leaves a zoo object at only the intersection of times, which we then extract.

library(zoo)
time(na.omit(do.call(cbind, lapply(foo, zoo, x = 1))))  # 2, 3

On 4/8/06, Andy Bunn <[hidden email]> wrote:

> > The original post is ambiguous: do you want to find the intersection or do
> > you want to find whether a prespecified set is in the
> > intersection? Patrick
> > provided you an answer to the latter while you provided an answer to the
> > former. Actually, I thought using table as you did (mod the need for no
> > replicates) was clever. A more direct but I think considerably slower
> > approach would be to use intersect() in a loop:
> >
> > inall<-intersect(foo[[1]],foo[[,2]])
> > for(i in seq(3, to=length(foo))inall<-intersect(inall,foo[[i]])
> >
> > I suspect you already thought of this and rejected it. Other than
> > transparency, I think the only advantage it has is that it will work for
> > something other than lists of numerics, e.g. it will work for lists of
> > factors, which the table() solution would not.
>
>
> Indeed, the first post was ambiguous. I was after the type of solution that I posted: the intersection rather than a prespecified set. Given that, I suppose my use of table is satisfactory.
>
> Thanks Patrick and Bert.
>
> -Andy
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html