List of Lists to Table R
2
0
Entering edit mode
9.2 years ago
moranr ▴ 290

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 • 17k views
ADD COMMENT
3
Entering edit mode
9.2 years ago
Chris S. ▴ 320

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")
ADD COMMENT
0
Entering edit mode
9.2 years ago
russhh 5.7k

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

sapply(BigList, function(sp.list) sp.list$name)
ADD COMMENT
0
Entering edit mode

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
ADD REPLY
1
Entering edit mode

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

ADD REPLY

Login before adding your answer.

Traffic: 2583 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6