Search code examples
rdataframenested-listsnamesstrsplit

cbind the i:th name of a list-of-lists to the i:th list


(please feel free to change the title to something more appropriate)

I have a list-of-lists like the one below. What I want to do is to cbind each names of each nested list to a new column in that list. In addition, I would like to strsplit each names by / so what is actually cbind are two columns, i.e. Nrep=rep1 and sp=sp1, each with the same number of rows as the nested list itself.

`rep1/sp1` <- read.table(text= "var,X2x,X4x,X6x
                101337,4.631833,4.4547,11.097333
                345754,3.727433,10.8560,10.536600" ,header=TRUE, sep=",")

`rep1/sp2` <- read.table(text= "var,X2x,X4x,X6x
               101337,5.631833,10.4547,11.097333
               345754,5.727433,12.8560,10.536600" ,header=TRUE, sep=",")

dflist <- list(`rep1/sp1`=`rep1/sp1`, `rep1/sp2`=`rep1/sp2`)

My idea was to try to do it in two steps; extracting the names + strsplit and then cbind each to the correct nested list, yielding an output as seen below. However, I can't get my head around how to the last step.

rep_sp <- names(dflist)
rep_sp <- strsplit(rep_sp, "/")
rep_sp <- lapply(rep_sp, function(x) data.frame(t(cbind(x))))
rep_sp <- ldply(rep_sp, data.frame)
colnames(rep_sp) <- c("Nrep","sp")

# hit the wall...

Desired output

> dflist
$`rep1/sp1`
Nrep  sp    var      X2x     X4x      X6x
rep1 sp1 101337 4.631833  4.4547 11.09733
rep1 sp1 345754 3.727433 10.8560 10.53660

$`rep1/sp2`
Nrep  sp    var      X2x     X4x      X6x
rep1 sp2 101337 5.631833 10.4547 11.09733
rep1 sp2 345754 5.727433 12.8560 10.53660

Any pointer on this would be very much appreciated, thanks!


Solution

  • If they don't have to be the first and second columns, then

    rep_sp <- names(dflist)
    rep_sp <- strsplit(rep_sp, "/")
    Map(cbind, dflist, 
        Nrep = sapply(rep_sp,'[',1),
        sp = sapply(rep_sp,'[',2))
    

    Will work and is pretty simple (using only base functions)

    $`rep1/sp1`
         var      X2x     X4x       X6x Nrep  sp
    1 101337 4.631833  4.4547 11.097333 rep1 sp1
    2 345754 3.727433 10.8560 10.536600 rep1 sp1
    
    $`rep1/sp2`
         var      X2x     X4x       X6x Nrep  sp
    1 101337 5.631833 10.4547 11.097333 rep1 sp2
    2 345754 5.727433 12.8560 10.536600 rep1 sp2
    

    The reason i didn't put them first is that when you use Map it will name the elements of the list using the first data parameter you pass. So by passing dflist first, i preserve those names. You could re-arrange the parameters and then just reset the names afterword with something like names(newobj)<-names(dflist)