2012-02-09 84 views
5

我正在尋找使用我的屏幕房地產看幾個簡單的列表並排。我不是想把它們合併起來,但我不介意是否創建了一個新的中間結構。當然,意識到列表可能有許多不同類型的對象,但我幾乎可以保證我的列表具有相同的結構;如果有必要,可以隨意插入「NA」或「NULL」,以便使其工作(或者我可以弄清楚如何解決這個問題)。如何在R中並排顯示列表 - 列表中的「cbind」?

這裏有三個例子列出了我想嘗試並排顯示方:

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個,而不會縮小爲小字體。

如果它可以更容易的e3條目l1l2可能是"FOSS",以匹配l3$e3的特徵向量,但真正的目標是在R控制檯的佈局問題。

一些幼稚的,特定的接口解決方案包括:

  • 火起來了多個存在的R情況下,使用GNU screenC-A |
  • 瞭解ESS,並讓Emacs的奇蹟解決一切畫面分割
  • 圍棋與另一個文本編輯器(例如Notepad ++)來回和手動遷移文本塊

非天真的解決方案t我正在嘗試的帽子是:

  • 將這些寫入文本文件。這裏的問題是制定固定寬度的間距。也許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)) 

回答

5

結合一些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] "                            " 
+0

+1這看起來不錯! – Iterator 2012-02-09 16:53:34

+0

你的答案就是我希望在基地R實現的結果。詹姆斯的回答實際上比我預期的要好得多,但你的基礎R解決方案贏得了「控制檯」獎(與安慰......相比)。 – Iterator 2012-02-12 14:11:16

2

這不是一個很乾淨的解決方案, 但你可以在列表轉換爲字符串, 把他們兩個單獨的文件, 並調用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") 
+0

+1我喜歡那樣。讓'diff'管理並排演示很聰明。 'diff'功能非常有用。如果有人想要所有東西,不難在每條線上添加一個對該源唯一的標記(即原始列表)。我只懷疑> 2個列表不能很好地工作。 – Iterator 2012-02-09 16:07:07

+0

您的想法也可以使用'paste'命令進行擴展。但是,不同文件的寬度會使結果變得粗糙。這導致我回到通過R與某種固定寬度+字符串截斷/填充結合的東西。這仍然會使用'capture.output()',這是個好主意,並且專注於* display *而不是列表對象的爭奪。 – Iterator 2012-02-09 16:14:43

0

爲什麼不使用unlist()?並欺騙他們成行?

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

您可以設置use.names=FALSE如果你不喜歡的E1 E2等

+0

這很有趣,但我的屏幕不*寬*。 :)一些文字會溢出。適合這些列而不是行,會更容易處理。 – Iterator 2012-02-09 16:51:48

+0

如果每個元素中的矢量> 1,則cbind()對unlist不起作用。 – 2012-02-09 18:06:46

3

你可以使用gplots::textplot

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

,有助於我們將窗口最大化。

+0

+1這也很不錯 - 這也是一個清晰,有用的顯示。 'mar'和'cex'的選項似乎很方便。 – Iterator 2012-02-09 17:55:21