2
votes

I needed to create a data frame from a specific sublist of a list. I know the data structure in this particular sublist is constant. For a single list I found do.call() would do the trick:

lst<-list(l1="aa", l2="ab", l3="ac")
fun.sublst1<-function(n) {
    a<-c("a",1,n)
    return(a)
 }
lstoflst<-lapply(lst, fun.sublst1)
do.call(rbind,lstoflst) # create a data frame from a list

However, If I have a list with lists and I want to iterate over a specific sublist, I am not able use do.call(rbind,lstoflst$A) to create the data frame.

# section list of list
fun.sublst2<-function(n) {
    a<-c("a",1,n)
    b<-c("b",2)
    return(list(A=a,B=b))
}
lstoflst<-lapply(lst, fun.sublst2)
# result should create a dataframe consisting of all sublists $A
t(cbind(lstoflst$l1$A,lstoflst$l2$A,lstoflst$l3$A))

With clumsy code it would look like that.

dat<-t(as.data.frame(lstoflst[[1]][[1]]))
for(i in 2:length(lstoflst)) {
     dat<-rbind(dat,t(lstoflst[[i]][[1]]))
}

Is there an elegant way to do it with the base R? I guess do.call(rbind,lstoflst, ???) with some other parameters will do. I suppose I need to pass the index or an indexing function. Any help?

I searched but I had no luck with my search term. Probably it has been solved already. Hope you can guide me anyway. Thanks

EDIT: changed headline because my examples only produce matrices as a result.

2
I'm not sure I follow. None of your examples actually creates a data frame. Are you aware that c() creates an atomic vector, not a list? - joran
Hi, well my sample solutions created matrices - class(dat). You are right. However, the problem is to create a (n x m) data type structure out of n list elements containing each a list with m atomic elements. Maybe my English is not well enough to express myself correctly. Additionally, my R-terms knowledge is on a low level I suppose. Sorry for any inconvenience. - Sebastian
OK I see the point with the data frame matrix difference in my work now. Obviously my example dat is not accurate enough. So instead c() I probably should have used a<-list(V1="a",V2=1,V3=n). However, I get it working with matrices as well. Thanks for clarifying it. - Sebastian

2 Answers

4
votes

If you know the name of the list component you want (in this case "A"), you can subset each of the lists within a list:

lsSub <- lapply(lstoflst, "[[", "A")

and then rbind that

do.call(rbind, lsSub)
#    [,1] [,2] [,3]
# l1 "a"  "1"  "aa"
# l2 "a"  "1"  "ab"
# l3 "a"  "1"  "ac"

But as Joran pointed out, that's not a data.frame

1
votes

This seems clunky, but works.

do.call(rbind, 
  lapply(lstoflst, function(x){xx <- x[names(x) %in% "A"]; do.call(rbind, xx)})
)

  [,1] [,2] [,3]
A "a"  "1"  "aa"
A "a"  "1"  "ab"
A "a"  "1"  "ac"

Perhaps somebody can do some clever stuff with rapply, but I couldn't get it to work.