2012-02-09 14 views
5

Estoy buscando utilizar mi pantalla inmobiliaria para ver varias listas simples una al lado de la otra. No estoy tratando de combinarlos, a la cbind, pero no me importaría si se creara una nueva estructura intermedia. Darse cuenta, por supuesto, de que una lista puede tener muchos tipos diferentes de objetos, aunque casi garantizaré que mis listas tengan las mismas estructuras; siéntete libre de insertar "NA" o "NULL" si es necesario para que las cosas funcionen (o puedo resolver cómo rebatir eso).¿Cómo se muestran las listas una al lado de la otra en R - un "cbind" para las listas?

Aquí hay tres ejemplo lista que me gustaría tratar de mostrar al lado del otro:

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

Si usted tiene una amplia pantalla, se ve como una pérdida para ver éstos ocupan tanto espacio vertical y tan poco espacio utilizado en el acceso horizontal. Si estas listas fueran solo un poco más largas, no podría ver más de 2 a la vez, sin reducir a una fuente pequeña.

Si lo hace más fácil, las entradas en e3l1 y l2 podría ser "FOSS", para que coincida con los vectores de caracteres de l3$e3, pero el objetivo real es un problema de diseño en la consola R.

Algunas soluciones ingenuas, específicos de la interfaz incluyen:

  • fuego hasta varias instancias R, pantalla dividida usando GNU screen y C-A |
  • Learn ESS, y dejar que el milagro de Emacs resuelve todo
  • Go ida y vuelta con otro editor de texto (por ejemplo, Notepad ++) y migrar manualmente bloques de texto

Las soluciones no ingenuas t lo que intento son:

  • Escríbalas en un archivo de texto. El problema aquí es resolver el espaciado de ancho fijo. Tal vez read.fwf ayudaría. (Está bien detenerse con un error si una entrada excede el espacio asignado, o truncar cosas).
  • Pruebe algo con el paquete reshape.
  • Posiblemente algo relacionado con xlsx, para crear un grupo de celdas, cada una con entradas de texto, y luego intentar mostrar una matriz de caracteres grandes.

¿Hay algún otro método que sea más eficiente? Nuevamente, nada realmente necesita combinarse como un objeto, solo se combina en la pantalla visual.


Actualización 1. Aquí hay un ejemplo con plyr. Los resultados son francamente crudos: los nombres de las listas y los elementos de la lista no se han conservado. No es demasiado difícil de solucionar, pero sospecho que es posible hacerlo mucho mejor que esto. Estoy de acuerdo con imprimir las listas ya que R normalmente las imprime, pero separando la ventana de alguna manera. Sospecho que no es fácil.

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

Respuesta

5

combinar algunos capture.output, lapply, gsub y format en un recipiente. Use do.call como agente aglutinante. Agregue paste al gusto. Deje reposar durante un tiempo:

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

Esto curar todo:

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 ¡Eso se ve bien! – Iterator

+0

Su respuesta es lo que esperaba lograr en la base R. La respuesta de James es realmente más atractiva de lo que esperaba, pero su solución R básica gana el premio de "consola" (en lugar de consuelo ...). – Iterator

2

Eso no es una solución muy limpia, pero se podía convertir las listas de cadenas, los pusieron en dos archivos separados, y llamar diff -y (o cualquier aplicación similar) para mostrar las diferencias entre el dos archivos. Siempre que las estructuras sean muy similares, se alinearán.

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 Me gusta eso. Dejar que 'diff' gestione la presentación lado a lado es inteligente. La funcionalidad 'diff' es bastante útil. Si uno quería todo, no es difícil anteponer cada línea con un token único para esa fuente (es decir, la lista original). Solo sospecho que las> 2 listas no funcionarán tan bien. – Iterator

+0

Su idea también se puede ampliar con el comando 'paste'. Sin embargo, el ancho de los diferentes archivos hace que los resultados sean irregulares. Esto me lleva de nuevo a combinar cosas a través de R con algún tipo de truncamiento/relleno de ancho fijo + cuerda. Esto todavía haría uso de 'capture.output()', que es una buena idea, y se enfoca en * display * en lugar de la disputa de los objetos de la lista. – Iterator

0

Por qué no usar unlist()? Y engañarlos en filas?

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

También podemos establecer use.names=FALSE si no le gusta la E1 E2 etc.

+0

Es interesante, pero mi pantalla no es * tan * ancha. :) Parte del texto se extenderá. Ajustar estas columnas, en lugar de filas, sería más fácil de procesar. – Iterator

+0

cbind() no funciona muy bien con unlist si tiene vectores> 1 en cada elemento. –

3

Usted podría utilizar gplots::textplot:

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

Esto ayuda a maximizar su primera ventana.

+0

+1 Eso también es bastante bueno: también es una pantalla clara y útil. Las opciones para 'mar' y' cex' parecen ser útiles. – Iterator

Cuestiones relacionadas