This is a test version of Biostars. For the public version, visit https://www.biostars.org.
List of Lists to Table R

Hi,

I have a list of lists object in R structured like follows:

$`UniqueSpecies Name`
                       name         rank     id
1        cellular organisms      no rank 131567
2                 Eukaryota superkingdom   2759
3              Opisthokonta      no rank  33154
4                   Metazoa      kingdom  33208
5                  Porifera       phylum   6040
6              Demospongiae        class   6042
7             Haplosclerida        order   6049
8                Niphatidae       family 178475
9                Amphimedon        genus 178513
10 Amphimedon queenslandica      species 400682

There are 127 Lists in the object.

I want to create a table like this:

Colnames = Species (a list with species names)

Each column will be column 1 of the above list i.e.

for(speciesName in BigList){
   coliwant <- speciesName[1]
}

It would look something like this:

       Species1    Species2     Species 3
rName1 coliwant1    coliwant2    coliwant3
rName2 coliwant1    coliwant2    coliwant3
rName3 coliwant1    coliwant2    coliwant3

I can create an empty data frame with 127 col names, but not sure how to add each list as a column.

Any help appreciated. Thanks.

r

2 answers

You could try to rbind your list, then select the ranks you want, and reshape using one of the many available methods here. Maybe something like...

y <- ldply(x, "rbind", .id="species")
z <-subset(y, rank %in% c("phylum", "order", "family") )
dcast(z, rank~species, value.var="name")

A reproducible example would help. However, does the following work?

sapply(BigList, function(sp.list) sp.list$name)

This returns a list. One thing I have just noticed is that each of the lists contain different number of rows.

I have done the following an got something more or less that I wanted:

cbind.fill <- function(...){
  nm <- list(...) 
  nm <- lapply(nm, as.matrix)
  n <- max(sapply(nm, nrow)) 
  do.call(cbind, lapply(nm, function (x) 
    rbind(x, matrix(, n-nrow(x), ncol(x))))) 
}

newdf<- data.frame()
for(i in BigList){
  curCol<-list()
  curCol<-i$name
  newdf <- cbind.fill(newdf, curCol)
}

colnames(newdf)<- Species

Personally, I'd only keep the data from $name that corresponds to one of the Linnaean ranks that are present in all of your species:

biglist <- lapply(1:3, function(i) data.frame(
  name = sample(letters[1:10]), 
  rank = paste('rank', i:(i+9))))
names(biglist) <- paste('sp', 1:3)
keep.ranks <- Reduce('intersect', lapply(biglist, function(sp.list) sp.list$rank))
sapply(biglist, function(sp.list) with(sp.list, name[match(keep.ranks, rank)]))

But that still looks like it will fail for things like 'no rank' where there may be multiple entries in a given sp.list

Log in to answer this question.