Home > database >  How to turn a list into a datataframe with a column that identifies each subelement of a list in R?
How to turn a list into a datataframe with a column that identifies each subelement of a list in R?

Time:08-26

Let's say I have the following list which I want to turn into a dataframe:

list1 = list(c("Text1","text2","text3","text4"),c("Text 1","text2","text3"),c("Text 3","text2"), c("Text 4"))

[[1]]
[1] "Text1" "text2" "text3" "text4"

[[2]]
[1] "Text 1" "text2"  "text3" 

[[3]]
[1] "Text 3" "text2" 

[[4]]
[1] "Text 4"

To turn a list into a dataframe, I do this:

data.frame(Text = matrix(unlist(list1)), stringsAsFactors = F)

    Text
1   Text1
2   text2
3   text3
4   text4
5  Text 1
6   text2
7   text3
8  Text 3
9   text2
10 Text 4

However, I lost track of which element belonged to which list. I would rather need the following output:


    ID    Text
1   1.1      Text1
2   1.2      text2
3   1.3      text3
4   1.4      text4
5   2.1      Text 1
6   2.2      text2
7   2.3      text3
8   3.1      Text 3
9   3.2      text2
10  4.1      Text 4

I'm stuck here unable to add another ID column where the first number indicates the number of the list and the second number denotes the sublist element in the nth list.

Can anyone help me with this?

Thanks!

CodePudding user response:

Use enframe and unnest

library(tidyverse)
enframe(list1, name = "ID", value = "text") %>% 
  unnest(text)
# A tibble: 10 × 2
      ID text  
   <int> <chr> 
 1     1 Text1 
 2     1 text2 
 3     1 text3 
 4     1 text4 
 5     2 Text 1
 6     2 text2 
 7     2 text3 
 8     3 Text 3
 9     3 text2 
10     4 Text 4

CodePudding user response:

Assign names to the list and stack():

stack(setNames(list1, seq_along(list1)))

   values ind
1   Text1   1
2   text2   1
3   text3   1
4   text4   1
5  Text 1   2
6   text2   2
7   text3   2
8  Text 3   3
9   text2   3
10 Text 4   4

CodePudding user response:

Another way in the tidyverse. This gives you two IDs for the list element and then vector element.

library(purrr)
library(tibble)

map_dfr(list1, enframe, name = "ID2", value = "text", .id = "ID")
# A tibble: 10 x 3
   ID      ID2 text  
   <chr> <int> <chr> 
 1 1         1 Text1 
 2 1         2 text2 
 3 1         3 text3 
 4 1         4 text4 
 5 2         1 Text 1
 6 2         2 text2 
 7 2         3 text3 
 8 3         1 Text 3
 9 3         2 text2 
10 4         1 Text 4

CodePudding user response:

I would do it this way:

data.frame(ID=paste0(rep(seq_along(list1), sapply(list1, length)),
                     '.',
                     unlist(sapply(list1, seq_along))),
           Text=unlist(list1))
#     ID   Text
# 1  1.1  Text1
# 2  1.2  text2
# 3  1.3  text3
# 4  1.4  text4
# 5  2.1 Text 1
# 6  2.2  text2
# 7  2.3  text3
# 8  3.1 Text 3
# 9  3.2  text2
# 10 4.1 Text 4

Another way to generate the IDs:

unlist(mapply(paste, 
              seq_along(list1), 
              sapply(list1, seq_along), 
              sep='.'))
  • Related