Reputation: 2685
I need to build a function that traverses lists and sublists recursively and then convert to data.frame. Let's say I have a list like that
from <- list(id="12345678", name="Gabriele")
message <- "The quick fox"
comments <- list(list(name="Mickey", comment="Hello world!"), list(name="Donald", message="World...hello!"))
big.list <- list(from, message, comments)
I need to convert it in the form of a data.frame with this schema
from_id, from_name, message, comments_name, comments_message
(in other words, flattening the sublists)
The problem is that I don't know in advance which fields I have in the lists and which I've not (for example, some posts may miss the comments section altogether).
Upvotes: 2
Views: 517
Reputation: 1417
Below is a quick trial. If big.list
has names, they can be taken as column names.
The inner do.call()
flattens the sub-list while the outer one converts into a data frame.
lst1 <- list(from = list(id="12345678", name="Gabriele"),message = "The quick fox",
comments = list(list(name="Mickey", comment="Hello world!"),
list(name="Donald", message="World...hello!")))
lst2 <- list(from = list(id="12345678", name="Gabriele"),message = "The quick fox",
comments = list(list(name="Mickey", comment="Hello world!")))
lst3 <- list(from = list(id="12345678", name="Gabriele"),message = "The quick fox")
df1 <- do.call(data.frame, do.call(c, lst1))
df2 <- do.call(data.frame, do.call(c, lst2))
df3 <- do.call(data.frame, do.call(c, lst3))
df1
#from.id from.name message comments1.name comments1.comment comments2.name comments2.message
#1 12345678 Gabriele The quick fox Mickey Hello world! Donald World...hello!
df2
#from.id from.name message comments.name comments.comment
#1 12345678 Gabriele The quick fox Mickey Hello world!
df3
#from.id from.name message
#1 12345678 Gabriele The quick fox
@ Gabriele B
Below is clumsy but working solution. Others may post a better one.
from <- list(id="12345678", name="Gabriele")
message <- "The quick fox"
comments <- list(list(name="Mickey", comment="Hello world!"), list(name="Donald", message="World...hello!"))
big.list <- list(from = from, message = message, comments = comments)
big.list1 <- list(from = from, message = message)
join <- function(lst) {
if(length(lst$comments) < 1) {
bnd <- data.frame(id = unlist(lst$from)[1], name = unlist(lst$from)[2], lst$message)
bnd$cmt.name <- "na"
bnd$comment <- "na"
bnd
} else {
bnd <- do.call(rbind, lapply(1:length(lst$comments), function(x) {
id <- unlist(lst$from)[1]
name <- unlist(lst$from)[2]
data.frame(id = id, name = name, lst$message)
}))
bnd <- cbind(bnd, do.call(rbind, lst$comments))
names(bnd) <- c("id", "name", "message", "cmt.name", "comment")
bnd
}
}
join(big.list)
#id name message cmt.name comment
#id 12345678 Gabriele The quick fox Mickey Hello world!
#id1 12345678 Gabriele The quick fox Donald World...hello!
join(big.list1)
#id name lst.message cmt.name comment
#id 12345678 Gabriele The quick fox na na
Upvotes: 1