【问题标题】:How to display lists side-by-side in R - a "cbind" for lists?如何在 R 中并排显示列表 - 列表的“cbind”?
【发布时间】:2012-02-09 15:42:22
【问题描述】:

我希望使用我的屏幕空间来并排查看几个简单的列表。我不想将它们结合起来,就像cbind,但我不介意是否创建了一个新的中间结构。当然,要意识到一个列表可能有许多不同类型的对象,尽管我几乎可以保证我的列表具有相同的结构;如有必要,请随意插入“NA”或“NULL”以使事情正常进行(或者我可以弄清楚如何解决这个问题)。

以下是我想尝试并排显示的三个示例列表:

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"))

如果您有一个宽显示器,看到这些显示器占用这么多垂直空间而在水平通道上占用这么少空间,这似乎是一种浪费。如果这些列表再长一点,我一次只能看到 2 个,而不会减少到小字体。

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

一些简单的、特定于接口的解决方案包括:

  • 启动多个 R 实例,使用 GNU screenC-A | 分屏
  • 学习 ESS,让 Emacs 奇迹解决一切
  • 使用另一个文本编辑器(例如 Notepad++)来回移动并手动迁移文本块

我正在尝试的非天真的解决方案是:

  • 将这些内容写入文本文件。这里的问题是制定固定宽度间距。也许read.fwf 会有所帮助。 (如果条目超出分配的空间,可以停止并出现错误,或者截断内容。)
  • 尝试使用 reshape 包。
  • 可能涉及xlsx,创建一堆单元格,每个单元格都有文本条目,然后尝试显示一个大字符矩阵。

还有其他更有效的方法吗?同样,实际上不需要将任何东西组合为一个对象,只需在视觉显示中组合即可。


更新 1. 这是一个使用 plyr 的示例。诚然,结果是相当粗糙的——列表和列表元素的名称没有被保留。这不是很难修复,但我怀疑有可能做得比这更好。我可以打印出列表,因为 R 通常会打印它们,但是以某种方式分隔窗口。我怀疑这并不容易。

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))

【问题讨论】:

    标签: r list object


    【解决方案1】:

    将一些capture.outputlapplygsubformat 组合到一个容器中。使用do.call 作为绑定代理。添加paste 品尝。让它酝酿一会儿:

    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=""))
    }
    

    这将治愈一切:

    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] "                                                                                                             "
    

    【讨论】:

    • 您的答案是我希望在 base R 中实现的。James 的答案实际上比我预期的更有吸引力,但您的 base R 解决方案赢得了“控制台”奖(相对于安慰奖)。 ..).
    【解决方案2】:

    你可以使用gplots::textplot:

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

    它有助于首先最大化您的窗口。

    【讨论】:

    • +1 这也很好 - 它也是一个清晰、有用的显示。 marcex 的选项似乎很方便。
    • 如果您显示屏幕截图,这将有助于了解这有多么有用。
    【解决方案3】:

    这不是一个非常干净的解决方案, 但您可以将列表转换为字符串, 将它们放在两个单独的文件中, 并致电diff -y(或任何类似的应用程序) 显示两个文件之间的差异。 只要结构非常相似, 它们将对齐。

    cat(capture.output( print(l1) ), sep="\n", file="tmp1")
    cat(capture.output( print(l2) ), sep="\n", file="tmp2")
    system("diff -y tmp1 tmp2")
    

    【讨论】:

    • +1 我喜欢这样。让diff 管理并排演示很聪明。 diff 功能非常有用。如果一个人想要所有东西,那么在每一行前面加上一个对该源唯一的标记(即原始列表)并不难。我只是怀疑 >2 个列表不会那么好。
    • 您的想法也可以使用paste 命令进行扩展。但是,不同文件的宽度使结果参差不齐。这使我回到通过 R 将事物与某种固定宽度 + 字符串截断/填充相结合。这仍然会使用capture.output(),这是一个好主意,并且专注于显示而不是列表对象的争吵。
    【解决方案4】:

    为什么不使用unlist()?把他们骗成行?

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

    如果你不喜欢 e1 e2 等,你可以设置use.names=FALSE

    【讨论】:

    • 这很有趣,但我的屏幕没有那么宽。 :) 一些文字会溢出。适合这些列,而不是行,会更容易处理。
    • cbind() 如果每个元素中的向量 > 1,则 cbind() 不能很好地与 unlist 一起使用。
    猜你喜欢
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多