Gregg-G
Gregg-G

Reputation: 45

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?

Upvotes: 0

Views: 54

Answers (2)

IRTFM
IRTFM

Reputation: 263342

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

Upvotes: 1

TarJae
TarJae

Reputation: 78927

We could use modify_depth from purrr package:

library(purrr)

my_nested_list <- list(list1, list2, list3)

second <- modify_depth(my_nested_list, 1, "second") %>% 
  unlist()
third <- modify_depth(my_nested_list, 1, "third") %>% 
  unlist()

desired_table <- cbind(second, third)
colnames(desired_table) <- c("second", "third")

desired_table
     second third
[1,]      2     3
[2,]     11    12
[3,]    101   102

Upvotes: 1

Related Questions