Convert list to data frame while saving list item names

I have a list where element names are identification tags and contains a vector with numeric values. They have an unequal (!) Length.

I want to convert it to a data frame where I have an identifier in one column and numeric values ​​in another column. For instance:

$`1` [1] 1 2 $`2` [1] 1 2 3 $`3` [1] 1 

To:

 ID Obs 1 1 1 2 2 1 2 2 2 3 3 1 
+6
source share
4 answers

Here is one way:

 ## your list ll <- list("1" = 1:2, "2" = 1:3, "3" = 1:2) ## convert to data.frame dl <- data.frame(ID = rep(names(ll), sapply(ll, length)), Obs = unlist(ll)) 

This gives:

 > dl ID Obs 11 1 1 12 1 2 21 2 1 22 2 2 23 2 3 31 3 1 32 3 2 

The first line in the data.frame() call is just some code to repeat the names() list as many times as necessary. The second line simply distinguishes the list that converts it to a vector.

+13
source

Use reshape2 and melt , which has the melt.list method

 .list <- list(`1` = 1:2, `2` = 1:3, `3` = 1:2) library(reshape2) melt(.list) ## value L1 ## 1 1 1 ## 2 2 1 ## 3 1 2 ## 4 2 2 ## 5 3 2 ## 6 1 3 ## 7 2 3 
+6
source

Basic solution

 List <- list('1'=c(1,2), '2'= c(1,2,3), '3'=1) x <- unlist(List) # as suggested by Gavin Simpson data.frame(ID=substr(names(x),1,1), Obs=x) ID Obs 11 1 1 12 1 2 21 2 1 22 2 2 23 2 3 3 3 1 

If you want rownames be 1,2,3,4,5,6 try this (using setNames ):

 data.frame(ID=substr(names(x),1,1), Obs=setNames(x, NULL)) ID Obs 1 1 1 2 1 2 3 2 1 4 2 2 5 2 3 6 3 1 

This solution only works if all the names are the same length, otherwise it will fail, and it would be better to use the Gavin solution. See for example:

 List2 <- list('week1'=c(1,2), 'week2'= c(1,2,3), 'week3'=1) x <- unlist(List2) data.frame(ID=substr(names(x),1,nchar(names(x)[1])-1), Obs=setNames(x, NULL)) ID Obs 1 week1 1 2 week1 2 3 week2 1 4 week2 2 5 week2 3 6 week3 1 
+1
source

A good and still missing alternative to already hosted solutions is the stack function:

 df <- stack(ll)[2:1] 

which gives:

 > df ind values 1 1 1 2 1 2 3 2 1 4 2 2 5 2 3 6 3 1 7 3 2 

Using setNames , you can get the format you want:

 df <- setNames(stack(ll)[2:1], c('ID','Obs')) 

which gives:

 > df ID Obs 1 1 1 2 1 2 3 2 1 4 2 2 5 2 3 6 3 1 7 3 2 

Used data:

 ll <- list("1" = 1:2, "2" = 1:3, "3" = 1:2) 
+1
source

Source: https://habr.com/ru/post/926502/


All Articles