Converting a list to a data frame

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

Converting a list to a data frame

Kevin E. Thorpe
There is probably a very simple elegant way to do this, but I have been
unable to find it. Here is a toy example. Suppose I have a list of data
frames like this.

  print(x <-
list('1'=data.frame(id=1:4,expand.grid(x1=0:1,x2=0:1)),'2'=data.frame(id=5:8,expand.grid(x1=2:3,x2=2:3))))
$`1`
   id x1 x2
1  1  0  0
2  2  1  0
3  3  0  1
4  4  1  1

$`2`
   id x1 x2
1  5  2  2
2  6  3  2
3  7  2  3
4  8  3  3

The real application will have more than 2 elements so I'm looking for a
general approach. I basically want to rbind the data frames in each list
element and add a variable that adds the element name. In this example
the result would look something like this.

rbind(data.frame(set='1',x[[1]]),data.frame(set='2',x[[2]]))
   set id x1 x2
1   1  1  0  0
2   1  2  1  0
3   1  3  0  1
4   1  4  1  1
5   2  5  2  2
6   2  6  3  2
7   2  7  2  3
8   2  8  3  3

Obviously, for 2 elements the simple rbind works but I would like a
general solution for arbitrary length lists. Hopefully that is clear.

Kevin

--
Kevin E. Thorpe
Head of Biostatistics,  Applied Health Research Centre (AHRC)
Li Ka Shing Knowledge Institute of St. Michael's Hospital
Assistant Professor, Dalla Lana School of Public Health
University of Toronto
email: [hidden email]  Tel: 416.864.5776  Fax: 416.864.3016

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
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.
Reply | Threaded
Open this post in threaded view
|

Re: Converting a list to a data frame

Charles Determan
Hi Kevin,

There may be a more elegant way but the following do.call and lapply should
solve your problem.

do.call(rbind, lapply(seq(length(x)), function(i) data.frame(set=i,
x[[i]])))

Regards,
Charles

On Fri, Nov 4, 2016 at 7:37 AM, Kevin E. Thorpe <[hidden email]>
wrote:

> There is probably a very simple elegant way to do this, but I have been
> unable to find it. Here is a toy example. Suppose I have a list of data
> frames like this.
>
>  print(x <- list('1'=data.frame(id=1:4,expand.grid(x1=0:1,x2=0:1)),'2'=
> data.frame(id=5:8,expand.grid(x1=2:3,x2=2:3))))
> $`1`
>   id x1 x2
> 1  1  0  0
> 2  2  1  0
> 3  3  0  1
> 4  4  1  1
>
> $`2`
>   id x1 x2
> 1  5  2  2
> 2  6  3  2
> 3  7  2  3
> 4  8  3  3
>
> The real application will have more than 2 elements so I'm looking for a
> general approach. I basically want to rbind the data frames in each list
> element and add a variable that adds the element name. In this example the
> result would look something like this.
>
> rbind(data.frame(set='1',x[[1]]),data.frame(set='2',x[[2]]))
>   set id x1 x2
> 1   1  1  0  0
> 2   1  2  1  0
> 3   1  3  0  1
> 4   1  4  1  1
> 5   2  5  2  2
> 6   2  6  3  2
> 7   2  7  2  3
> 8   2  8  3  3
>
> Obviously, for 2 elements the simple rbind works but I would like a
> general solution for arbitrary length lists. Hopefully that is clear.
>
> Kevin
>
> --
> Kevin E. Thorpe
> Head of Biostatistics,  Applied Health Research Centre (AHRC)
> Li Ka Shing Knowledge Institute of St. Michael's Hospital
> Assistant Professor, Dalla Lana School of Public Health
> University of Toronto
> email: [hidden email]  Tel: 416.864.5776  Fax: 416.864.3016
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posti
> ng-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
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.
Reply | Threaded
Open this post in threaded view
|

Re: Converting a list to a data frame

Carlos Ortega-2
In reply to this post by Kevin E. Thorpe
Hi,

You have also "rbindlist()" function in package "data.table" that does
exactly what you need.

Kind Regards,
Carlos Ortega
www.qualityexcellence.es



2016-11-04 13:37 GMT+01:00 Kevin E. Thorpe <[hidden email]>:

> There is probably a very simple elegant way to do this, but I have been
> unable to find it. Here is a toy example. Suppose I have a list of data
> frames like this.
>
>  print(x <- list('1'=data.frame(id=1:4,expand.grid(x1=0:1,x2=0:1)),'2'=
> data.frame(id=5:8,expand.grid(x1=2:3,x2=2:3))))
> $`1`
>   id x1 x2
> 1  1  0  0
> 2  2  1  0
> 3  3  0  1
> 4  4  1  1
>
> $`2`
>   id x1 x2
> 1  5  2  2
> 2  6  3  2
> 3  7  2  3
> 4  8  3  3
>
> The real application will have more than 2 elements so I'm looking for a
> general approach. I basically want to rbind the data frames in each list
> element and add a variable that adds the element name. In this example the
> result would look something like this.
>
> rbind(data.frame(set='1',x[[1]]),data.frame(set='2',x[[2]]))
>   set id x1 x2
> 1   1  1  0  0
> 2   1  2  1  0
> 3   1  3  0  1
> 4   1  4  1  1
> 5   2  5  2  2
> 6   2  6  3  2
> 7   2  7  2  3
> 8   2  8  3  3
>
> Obviously, for 2 elements the simple rbind works but I would like a
> general solution for arbitrary length lists. Hopefully that is clear.
>
> Kevin
>
> --
> Kevin E. Thorpe
> Head of Biostatistics,  Applied Health Research Centre (AHRC)
> Li Ka Shing Knowledge Institute of St. Michael's Hospital
> Assistant Professor, Dalla Lana School of Public Health
> University of Toronto
> email: [hidden email]  Tel: 416.864.5776  Fax: 416.864.3016
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posti
> ng-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>



--
Saludos,
Carlos Ortega
www.qualityexcellence.es

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
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.
Reply | Threaded
Open this post in threaded view
|

Re: Converting a list to a data frame

Bert Gunter-2
In reply to this post by Charles Determan
I believe that a slightly more efficient way of doing this without
leaving base R is:

cbind(do.call(rbind,x), set = rep(seq_along(x), vapply(x,nrow,1)) )


Cheers,
Bert


Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Fri, Nov 4, 2016 at 5:50 AM, Charles Determan <[hidden email]> wrote:

> Hi Kevin,
>
> There may be a more elegant way but the following do.call and lapply should
> solve your problem.
>
> do.call(rbind, lapply(seq(length(x)), function(i) data.frame(set=i,
> x[[i]])))
>
> Regards,
> Charles
>
> On Fri, Nov 4, 2016 at 7:37 AM, Kevin E. Thorpe <[hidden email]>
> wrote:
>
>> There is probably a very simple elegant way to do this, but I have been
>> unable to find it. Here is a toy example. Suppose I have a list of data
>> frames like this.
>>
>>  print(x <- list('1'=data.frame(id=1:4,expand.grid(x1=0:1,x2=0:1)),'2'=
>> data.frame(id=5:8,expand.grid(x1=2:3,x2=2:3))))
>> $`1`
>>   id x1 x2
>> 1  1  0  0
>> 2  2  1  0
>> 3  3  0  1
>> 4  4  1  1
>>
>> $`2`
>>   id x1 x2
>> 1  5  2  2
>> 2  6  3  2
>> 3  7  2  3
>> 4  8  3  3
>>
>> The real application will have more than 2 elements so I'm looking for a
>> general approach. I basically want to rbind the data frames in each list
>> element and add a variable that adds the element name. In this example the
>> result would look something like this.
>>
>> rbind(data.frame(set='1',x[[1]]),data.frame(set='2',x[[2]]))
>>   set id x1 x2
>> 1   1  1  0  0
>> 2   1  2  1  0
>> 3   1  3  0  1
>> 4   1  4  1  1
>> 5   2  5  2  2
>> 6   2  6  3  2
>> 7   2  7  2  3
>> 8   2  8  3  3
>>
>> Obviously, for 2 elements the simple rbind works but I would like a
>> general solution for arbitrary length lists. Hopefully that is clear.
>>
>> Kevin
>>
>> --
>> Kevin E. Thorpe
>> Head of Biostatistics,  Applied Health Research Centre (AHRC)
>> Li Ka Shing Knowledge Institute of St. Michael's Hospital
>> Assistant Professor, Dalla Lana School of Public Health
>> University of Toronto
>> email: [hidden email]  Tel: 416.864.5776  Fax: 416.864.3016
>>
>> ______________________________________________
>> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posti
>> ng-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> 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.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
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.