Search code examples
rlistkableextra

How to summarize a portion of a group of lists into a table


I am trying to pull the results of several queries into a single table. All of the results are in a list of lists, often as single numbers from a statistical evaluation. I also need to be able to specify which of the lists results I want to tabulate. For an example set of lists:

list1 <- list(1, 2, 3, 4)
  names(list1) <- c("first", "second", "third", "fourth")
list2 <- list(10, 11, 12, 13)
  names(list2) <- c("first", "second", "third", "fourth")
list3 <- list(100, 101, 102, 103)
  names(list3) <- c("first", "second", "third", "fourth")

I can grab the results individually from each list:

library(magrittr)

row1 <- list1[c("second", "third")] %>%
  rbind() %>%
  unlist()

row2 <- list2[c("second", "third")] %>%
  rbind() %>%
  unlist()

row3 <- list3[c("second", "third")] %>%
  rbind() %>%
  unlist()

then add them to a data frame, then name each column, and final print the result

library(kableExtra)
desired_table <- rbind(row1, row2, row3)
colnames(desired_table) <- c("second", "third")

kbl(desired_table)

It seems to me like there should be an easier way, and I expect there is.

How can I do this with a list of package results, either with another package or in a way that I have not thought of?


Solution

  • Like "$", the square-bracket is a an infix operator that is a disguised function call. You could even write "["(list(0,1,2,3), 1), and expect to get 0.

    The sapply function is creating successive calls, the first of which is list(list1,list2,list3)[[1]][ c("second", "third") ], the second list(list1,list2,list3)[[2]][ c("second", "third") ], etc. Underneath the hood, sapply and lappy are just disguised for-loops with an implicit sequential integer iterator.

    Here's a base application of a composition of a couple of standard R functions ("[" aned sapply) that does it as a one liner:

    t( sapply( list(list1,list2,list3), "[", c("second", "third") ) )
         second third
    [1,] 2      3    
    [2,] 11     12   
    [3,] 101    102  
    
    library(kableExtra)
    desired_table <- t( sapply(list(list1,list2,list3), "[", c("second", "third") ) )
    png()
    kbl(desired_table); dev.off()
    

    Might want to add a bit of space between those two columns:

    enter image description here