Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display lists side-by-side in R - a "cbind" for lists?

Tags:

object

list

r

I am looking to use my screen real estate to look at several simple lists side by side. I'm not trying to combine them, a la cbind, but I wouldn't mind if a new intermediate structure were created. Realize, of course, that a list may have many different types of objects, though I will almost guarantee that my lists have the same structures; feel free to insert "NA" or "NULL" if necessary to make things work (or I can figure out how to wrangle that).

Here are three example lists that I would like to try to display side by side:

l1 <- list(e1 = "R", e2 = list("statistics", "visualization"), e3 = 0)
l2 <- list(e1 = "Perl", e2 = list("text processing", "scripting"), e3 = 0)
l3 <- list(e1 = "Matlab", e2 = list("numerical computing", "simulation"), e3 = c("academic - unknown", "professional - unknown"))

If you have a wide monitor, it looks like a waste to see these take up so much vertical room and so little room used on the horizontal access. If these lists were just a little longer, I wouldn't be able to see more than 2 at a time, without reducing to a small font.

If it makes it easier, the e3 entries in l1 and l2 could be "FOSS", to match the character vectors of l3$e3, but the real goal is a layout problem in the R console.

Some naive, interface-specific solutions include:

  • Fire up multiple R instances, split screen using GNU screen and C-A |
  • Learn ESS, and let the miracle of Emacs solve everything
  • Go back and forth with another text editor (e.g. Notepad++) and manually migrate blocks of text

The non-naive solutions that I'm trying are:

  • Write these out to a text file. The problem here is working out fixed width spacing. Maybe read.fwf would help. (It's okay to stop with an error if an entry would exceed the allotted space, or to truncate stuff.)
  • Try something with the reshape package.
  • Possibly something involving xlsx, to create a bunch of cells, each with text entries, and then attempt to display a big character matrix.

Are there some other methods that would be more efficient? Again, nothing really needs to be combined as an object, just combined in the visual display.


Update 1. Here is an example using plyr. The results are admittedly quite crude - names of lists and list elements have not been preserved That's not too hard to fix, but I suspect it's possible to do much better than this. I'm okay with printing out the lists as R normally prints them, but separating the window in some way. I have a suspicion that's not easy.

combineLists <- function(manyLists){
    library(plyr)
    newLists <- list()
    for(ixList in 1:length(manyLists)){
        tmpList <- lapply(manyLists[[ixList]], paste, sep = "", collapse = ", ")
        tmpVec  <- as.character(tmpList)
        newLists[[ixList]] <- tmpVec
    }
    newDF   <- t(ldply(newLists))
    return(newDF)
}

combineLists(list(l1, l2, l3))
like image 785
Iterator Avatar asked Feb 09 '12 15:02

Iterator


People also ask

How do I add two lists in R?

R provided two inbuilt functions named c() and append() to combine two or more lists. c() function in R language accepts two or more lists as parameters and returns another list with the elements of both the lists.

How do I add one list to another list in R?

To add or append an element to the list in R use append() function. This function takes 3 parameters input list, the string or list you wanted to append, and position. The list. append() function from the rlist package can also use to append one list with another in R.

How do you access part of a list in R?

Accessing List Elements. Elements of the list can be accessed by the index of the element in the list. In case of named lists it can also be accessed using the names.

How do I print a list side by side in Python?

You can use the zip() function to join lists together. The zip() function will iterate tuples with the corresponding elements from each of the lists, which you can then format as Michael Butscher suggested in the comments. Finally, just join() them together with newlines and you have the string you want.


2 Answers

Combine some capture.output, lapply, gsub and format into a container. Use do.call as a binding agent. Add paste to taste. Let it brew for a while:

sidebyside <- function(..., width=60){
  l <- list(...)
  p <- lapply(l, function(x){
        xx <- capture.output(print(x, width=width))
        xx <- gsub("\"", "", xx)
        format(xx, justify="left", width=width)
      }
  )
  p <- do.call(cbind, p)
  sapply(seq_len(nrow(p)), function(x)paste(p[x, ], collapse=""))
}

This will cure everything:

sidebyside(l1, l2, l3, width=30)

 [1] "$e1                           $e1                           $e1                                              "
 [2] "[1] R                         [1] Perl                      [1] Matlab                                       "
 [3] "                                                                                                             "
 [4] "$e2                           $e2                           $e2                                              "
 [5] "$e2[[1]]                      $e2[[1]]                      $e2[[1]]                                         "
 [6] "[1] statistics                [1] text processing           [1] numerical computing                          "
 [7] "                                                                                                             "
 [8] "$e2[[2]]                      $e2[[2]]                      $e2[[2]]                                         "
 [9] "[1] visualization             [1] scripting                 [1] simulation                                   "
[10] "                                                                                                             "
[11] "                                                                                                             "
[12] "$e3                           $e3                           $e3                                              "
[13] "[1] 0                         [1] 0                         [1] academic - unknown     professional - unknown"
[14] "                                                                                                             "
like image 80
Andrie Avatar answered Nov 14 '22 23:11

Andrie


You could use gplots::textplot:

library(gplots)
textplot(cbind(l1,l2,l3))

It helps to maximise your window first.

like image 32
James Avatar answered Nov 14 '22 22:11

James