Reputation: 413
Having a named list such as :
set.seed(1)
list <- list(table(sample(LETTERS[1:10], 50, replace = T)), table(sample(LETTERS[1:20], 50, replace = T)))
names(list) <- LETTERS[1:2]
How can one convert this list into a data frame that fills the gaps with the element's names?
For example, the code below gives an error due to different row numbers:
as.data.frame(list)
Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, :
arguments imply differing number of rows: 10, 18
manually is possible for this small table by doing like this:
rbind(data.frame(Name = "A", Letters = list$A), data.frame(Name = "B", Letters = list$B))
Name Letters.Var1 Letters.Freq
1 A A 3
2 A B 3
3 A C 3
4 A D 4
5 A E 6
6 A F 6
7 A G 6
8 A H 3
9 A I 8
10 A J 8
11 B A 3
12 B B 2
13 B D 1
14 B F 4
15 B G 5
16 B H 4
17 B I 1
18 B J 3
19 B K 3
20 B L 3
21 B M 4
22 B N 3
23 B O 1
24 B P 4
25 B Q 2
26 B R 2
27 B S 4
28 B T 1
Would you know how to scale this for a list with dozens of tables?
Thanks for the help.
Upvotes: 1
Views: 178
Reputation: 24790
If you prefer data.table
:
library(data.table)
rbindlist(Map(stack,list),idcol = "Name")
# Name values ind
# 1: A 3 A
# 2: A 3 B
# 3: A 3 C
# 4: A 4 D
# 5: A 6 E
# 6: A 6 F
#...
Upvotes: 2
Reputation: 388982
You can use purrr
's map_df
:
result <- purrr::map_df(list, as.data.frame, .id = 'Name')
result
# Name Var1 Freq
#1 A A 3
#2 A B 3
#3 A C 3
#4 A D 4
#5 A E 6
#6 A F 6
#7 A G 6
#8 A H 3
#9 A I 8
#10 A J 8
#11 B A 3
#12 B B 2
#13 B D 1
#14 B F 4
#15 B G 5
#16 B H 4
#17 B I 1
#18 B J 3
#19 B K 3
#20 B L 3
#21 B M 4
#22 B N 3
#23 B O 1
#24 B P 4
#25 B Q 2
#26 B R 2
#27 B S 4
#28 B T 1
Base R is bit more verbose but can be achieved as :
tmp <- lapply(list, as.data.frame)
do.call(rbind, Map(cbind, Name = names(tmp), tmp))
Upvotes: 4