Florent
Florent

Reputation: 1928

How to convert a nested lists to dataframe in R?

I'm have a nested list I would like to convert to a dataframe.

iter1 <- list(item1 = 1, item2 = "a")
iter2 <- list(item1 = 1, item2 = "b")
All <- list(iter1 = iter1, iter2 = iter2)

df <- data.frame(t(sapply(All,c))) # Convert list to dataframe

But my problem is that df$iter1 returns a list instead of a dataframe, any idea ?

> class(df)
[1] "data.frame"

> df$item1
$iter1
[1] 1

$iter2
[1] 1

I have the same problem when converting with do.call : df <- data.frame(do.call(rbind, All)) but I can't figure out what is wrong.

Upvotes: 4

Views: 7088

Answers (3)

d.b
d.b

Reputation: 32538

temp = unique(unlist(lapply(All, names)))
mydf = setNames(object = data.frame(lapply(temp, function(nm)
    unlist(lapply(All, function(x) x[[nm]])))), nm = temp)

mydf
#      item1 item2
#iter1     1     a
#iter2     1     b

OR

do.call(rbind, lapply(All, data.frame))
#      item1 item2
#iter1     1     a
#iter2     1     b

OR

data.table::rbindlist(All, idcol = TRUE)
#     .id item1 item2
#1: iter1     1     a
#2: iter2     1     b

Upvotes: 3

S.C
S.C

Reputation: 740

I think you want the first column to be a numeric vector as 1,1 and the second column to be a character vector as "a" and "b"?

How about this:

iter1 <- list(item1 = 1, item2 = "a")
iter2 <- list(item1 = 1, item2 = "b")
All <- list(iter1 = iter1, iter2 = iter2)

extract <- function(x, listx) sapply(listx, "[[", x)

df <- lapply(1:2, extract, All)
df <- as.data.frame(df, col.names = names(All), stringsAsFactors = F)
df

And if you want a one-liner:

df <- as.data.frame(lapply(1:2, function(x, listx) sapply(listx, "[[", x), All), col.names = names(All), stringsAsFactors = F)
df

Upvotes: 0

user3375672
user3375672

Reputation: 3768

Would lapply do what you want ?:

iter1 <- list(item1 = 1, item2 = "a")
iter2 <- list(item1 = 1, item2 = "b")
All <- list(iter1 = iter1, iter2 = iter2)

And then:

df <- as.data.frame(lapply(All, unlist))

> str(df)
'data.frame':   2 obs. of  2 variables:
 $ iter1: Factor w/ 2 levels "1","a": 1 2
 $ iter2: Factor w/ 2 levels "1","b": 1 2

Upvotes: 1

Related Questions