简体   繁体   English

如何在 R 中并排显示列表 - 列表的“cbind”?

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

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.我并没有尝试将它们组合起来,a la cbind ,但我不介意是否创建了一个新的中间结构。 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).如有必要,请随意插入“NA”或“NULL”以使事情正常进行(或者我可以弄清楚如何解决这个问题)。

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.如果这些列表再长一点,我一次看不到超过 2 个,除非字体变小。

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.如果它更容易, l1l2中的e3条目可以是"FOSS" ,以匹配l3$e3的字符向量,但真正的目标是 R 控制台中的布局问题。

Some naive, interface-specific solutions include:一些简单的、特定于接口的解决方案包括:

  • Fire up multiple R instances, split screen using GNU screen and CA |启动多个 R 实例,使用 GNU screenCA |
  • Learn ESS, and let the miracle of Emacs solve everything学好ESS,让Emacs的奇迹解决一切
  • Go back and forth with another text editor (eg Notepad++) and manually migrate blocks of text与另一个文本编辑器(例如Notepad++)来回并手动迁移文本块

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.也许read.fwf会有所帮助。 (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.尝试使用reshape包。
  • Possibly something involving xlsx , to create a bunch of cells, each with text entries, and then attempt to display a big character matrix.可能涉及xlsx的东西,创建一堆单元格,每个单元格都有文本条目,然后尝试显示一个大字符矩阵。

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 .更新 1. 这是一个使用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.我可以像 R 通常打印的那样打印列表,但以某种方式分隔窗口。 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))

Combine some capture.output , lapply , gsub and format into a container. 将一些capture.outputlapplygsubformat到一个容器中。 Use do.call as a binding agent. 使用do.call作为绑定代理。 Add paste to taste. 添加paste口味。 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] "                                                                                                             "

You could use gplots::textplot : 你可以使用gplots::textplot

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

It helps to maximise your window first. 它有助于最大化您的窗口。

That is not a very clean solution, but you could convert the lists to strings, put them in two separate files, and call diff -y (or any similar application) to display the differences between the two files. 这不是一个非常干净的解决方案,但您可以将列表转换为字符串,将它们放在两个单独的文件中,并调用diff -y (或任何类似的应用程序)来显示两个文件之间的差异。 Provided the structures are very similar, they will be aligned. 如果结构非常相似,它们将是对齐的。

cat(capture.output( print(l1) ), sep="\n", file="tmp1")
cat(capture.output( print(l2) ), sep="\n", file="tmp2")
system("diff -y tmp1 tmp2")
    a <- c("a", "b", "c")
    b <- c("1", "2", "3")

    for (i in 1:length(a)){
      cat(paste0(a[i] , " ", b[i]), sep = "\n")}'

Output:输出:
a 1一个 1
b 2乙二
c 3 3

Why not use unlist() ? 为什么不使用unlist() And cheat them into rows? 并欺骗他们成行?

for(x in 1:3) { 
print(rbind(unlist(get(paste("l",x,sep="")))))
}

You could set use.names=FALSE if you don't like the e1 e2 etc. 如果您不喜欢e1 e2等,可以设置use.names=FALSE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM