I have this list in R:
my_list = list("word",c("word", "word"), "word", c("word", "word","word"), "word")
[[1]]
[1] "word"
[[2]]
[1] "word" "word"
[[3]]
[1] "word"
[[4]]
[1] "word" "word" "word"
[[5]]
[1] "word"
I would like to convert this list into a data frame that looks something like this:
col1 col2 col3
1 word
2 word word
3 word
4 word word word
5 word
# source code of the desired output
structure(list(col1 = c("word", "word", "word", "word", "word"
), col2 = c("", "word", "", "word", ""), col3 = c("", "", "",
"word", "")), class = "data.frame", row.names = c(NA, -5L))
I tried to use the answer provided here (How to split a column of list into several columns using R) for my question:
z = my_list
x <- do.call(rbind, z)
colnames(x) <- LETTERS[1:ncol(x)]
h = data.frame(cbind(z[c("sg", "time")], x))
But this is not giving me the desired output.
Can someone please show me how to do this?
Thank you!
CodePudding user response:
You could use lapply
to make the list element lengths the same, then do.call
with rbind
to create the desired output:
do.call(rbind, lapply(my_list, `length<-`, max(lengths(my_list))))
Output
# [,1] [,2] [,3]
# [1,] "word" NA NA
# [2,] "word" "word" NA
# [3,] "word" NA NA
# [4,] "word" "word" "word"
# [5,] "word" NA NA
If you wanted there to be blanks as opposed to NA
values:
new_df <- do.call(rbind, lapply(my_list, `length<-`, max(lengths(my_list))))
new_df[is.na(new_df)] <- ""
Output:
# [,1] [,2] [,3]
# [1,] "word" "" ""
# [2,] "word" "word" ""
# [3,] "word" "" ""
# [4,] "word" "word" "word"
# [5,] "word" "" ""
CodePudding user response:
With stringi::stri_list2matrix
:
library(stringi)
data.frame(stri_list2matrix(my_list, byrow = TRUE))
# X1 X2 X3
# 1 word <NA> <NA>
# 2 word word <NA>
# 3 word <NA> <NA>
# 4 word word word
# 5 word <NA> <NA>
Or with sapply
:
t(sapply(my_list, "length<-", max(lengths(my_list))))