Search code examples
rloopslapplyreporters

lapply of list in ReporteRs packages


I have a list of names and list of table which create in ReporteRs packages, called "MyFTable", I tried to apply list of MyFTable with list of t

t1 <- c("a","b","c")
t2 <- c("d","e","f")
t <- list(t1, t2)

If I do separately, it works, but when I put in the loop, it doesn't work.

  addHeaderRow(MyFTable[[1]], value=c("", t1))
  addHeaderRow(MyFTable[[2]], value=c("", t2))

This is my attempt:

  for(i in 1: length(MyFTable)){
  lapply(MyFTable[[i]],function(x) addHeaderRow(x, value=c("",t[[i]])))
}

for(i in 1: length(MyFTable)){
  lapply(MyFTable[[i]],function(x) addHeaderRow(x[[i]], value=c("",t[[i]])))
}

I got error :

x must be a FlexTable

Thanks for your advice.


Solution

  • You are adding lapply for no good reason. You can do that in a regular loop.

    out <- vector("list", length(MyFTable)) # always pre-allocate
    
    for(i in 1:length(MyFTable)){
      out[[i]] <- addHeaderRow(MyFTable[[i]], value=c("",t[[i]])))
    }
    

    You can also use mapply which works on corresponding elements from all provided objects (in this case mft and tt).

    myFun <- function(mft, tt) addHeaderRow(mft, tt)
    mapply(FUN = myFun, mft = MyFTable, tt = t)
    

    If you are hell-bent on lapply, you could "hide a loop".

    lapply(1:length(MyFTable), FUN = function(i, mft, tt) {
      addHeaderRow(mft[[i]], value = c("", tt[[i]]))
    }, mft = MyFTable, tt = t)
    

    This last piece of code is interesting because it's easy to show how debugging works in R. By setting browser() at some point in a function, the execution will stop at that point and you can either inspect elements or advance by typing n or c. First command will move one line forward (from browser() call) and c will execute the current "loop" and wait at the browser() line in the next loop (if not finished, then it exists).

    Try it, execute

    lapply(1:length(MyFTable), FUN = function(i, mft, tt) {
      browser()
      addHeaderRow(mft[[i]], value = c("", tt[[i]]))
    }, mft = MyFTable, tt = t)
    

    and your prompt should change a bit. Inspect elements i, mft and tt and see if they match your MyFTable[[1]] and t[[1]] elements. To quit, type Q.