15  SALIDAS

Hay dos niveles desde los cuáles se considera el manejo de las salidas de R.

  1. A nivel de usuario. A este nivel se busca organizar los resultados generados por R en un documento que pueda editarse para construir el informe final, o que por sí solo cumpla esa función.

  2. A nivel de programador. Cuando se construyen funciones personalizadas (cf. capítulo 21) debe controlarse la forma en la que se presentan las salidas para el usuario final.

15.1 Organización de salidas a nivel de usario

Cuando se trabaja con R en un proyecto de análisis, bien sea usando las funciones nucleares del sistema, algunas otras escritas por terceros o algunas funciones personalizadas que se hubieran creado previamente, se requiere hilar los resultados generados por R con las correspondientes interpretaciones, para construir un documento legible que pueda servir de base al informe final o constituirse como tal.

La herramienta más potente para alcanzar este objetivo es Quarto. Invitamos a consultarla en el libro Quarto.

¡Use Quarto!

Quarto es un sistema de publicación que se integra con R para estructurar documentos elegantemente formateados.

En los documentos generados por Quarto se intercalan los resultados con las interpretaciones redactadas por el usuario. Opcionalmente también pueden incluir el código R.

Esta es la herramienta recomendada.

15.2 Organización de salidas a nivel de programador

En esta sección se presentan las principales funciones para imprimir cadenas de caracteres en el dispositivo de salida (por defecto, la consola). Se destacan print, cat, paste, strwrap, WriteLines y c.

15.2.1 print

La función print despliega en consola la información de su argumento sin alterar su contenido. Esta es la única función de visualización que admite objetos de cualquier clase.

Considérese el data frame df y su visualización a través de la consola:

id <- c("a23", "f31", "j33", "m54")
v1 <- c(2.4, 7.9, 1.1, 8.5)
v2 <- c(4+3i, 2-0.8i, 1+1.1i, 3-5i)
df <- data.frame(id, v1, v2)
print(df)
   id  v1     v2
1 a23 2.4 4+3.0i
2 f31 7.9 2-0.8i
3 j33 1.1 1+1.1i
4 m54 8.5 3-5.0i

La función print es la que debe usarse para enviar a consola la información de los contenedores de datos. Asimismo, es la que se usa para enviar a consola la información de otros objetos, como modelos, tablas, resúmenes y funciones.

Considérese ahora el envío de una cadena de caracteres a la consola:

print("Tabla resumen")
[1] "Tabla resumen"

La función print no suele usarse para el envío de texto a la consola, por los aspectos indeseables que exhibe la salida anterior: la cadena de texto aparece entrecomillada1 y está antecedida por el marcador de posición.

15.2.2 cat

La función cat (nemotécnicamente: concatenación) es una de las más utilizadas para presentar avisos en consola.

El principal uso de cat es la concatenación de diferentes cadenas de caracteres, combinando información contenida en los argumentos o en la salida de una función con texto personalizado.

a <- c(3, 5, 12, 9)
cat("La media es", mean(a), "\n",  "La desviación estándar es", sd(a))
La media es 7.25 
 La desviación estándar es 4.031129

Los diferentes elementos de cat se separan por defecto con un espacio. Esta es la razón por la que la segunda línea, después del salto de línea, aparece con un espacio de indentación con respecto a la primera.

Es posible modificar este comportamiento mediante el argumento sep. Así, si se quisiera, por ejemplo, eliminar los espacios, se usaría sep = "". No obstante, en este caso sería necesario incorporar manualmente los espacios en todos los sitios requeridos (después de es), así:

a <- c(3, 5, 12, 9)
cat("La media es ", mean(a), "\n",  "La desviación estándar es ", sd(a),
    sep = "")
La media es 7.25
La desviación estándar es 4.031129

15.2.2.1 Salto de línea

La etiqueta "\n" genera un salto de línea. Para genera múltiples saltos, pueden combinarse varios elementos \n dentro de una etiqueta.

Así, para generar 2 saltos de línea, se escribe así:

cat("La media es", mean(a), "\n\n",  "La desviación estándar es", sd(a))
La media es 7.25 

 La desviación estándar es 4.031129

Para generar 3 saltos de línea, se usaría "\n\n\n".

Las etiquetas de salto de línea, ya sean simples o múltiples, pueden usarse al principio o al final de una cadena de caracteres, pegadas de su contenido, así:

cat("La media es", mean(a), "\nLa desviación estándar es", sd(a))
La media es 7.25 
La desviación estándar es 4.031129
¿¡Y qué pasó con la indentación!?

Se observa que al introducir el(los) salto(s) de línea al inicio de una cadena de caracteres, desaparece la indeseable indentación.

Esto es debido a que, con la configuración por defecto de cat, que deja un espacio entre elementos, se aplica un espacio después de la etiqueta "\n" (después del salto de línea).

En contraste, cuando se incorpora al inicio de alguna otra cadena de caracteres, el espacio se genera antes de realizar el salto de línea, quedando al final de la línea anterior, siendo, por tanto, invisible.

Obsérvese lo que sucede al incorporar la etiqueta \n al final de una cadena de caracteres:

cat("Coeficiente de variación:", sd(a)/mean(a), "%\n", "Media:", mean(a))
Coeficiente de variación: 0.5560178 %
 Media: 7.25
¿¡Por qué regresó la indentación!?

La inclusión de la etiqueta de salto al final de la línea, aunque también es válida, no evita la indentación en la segunda línea.

Esto es debido a que el espacio, que por defecto se aplica entre los diferentes elementos de cat, va luego de cada elemento.

Así, la instrucción:

cat("a\n", "b")

Se interpreta como:

  1. imprimir a
  2. realizar el salto de línea
  3. introducir un espacio (que aparece al comienzo de la segunda línea)
  4. imprimir b

Mientras que la instrucción:

cat("a", "\nb")

Se interpreta como:

  1. imprimir a
  2. introducir un espacio (que va al final de la primera línea y, por tanto, es invisible)
  3. realizar el salto de línea
  4. imprimir b

Luego, para evitar las indentaciones en las líneas que siguen a la primera, debe introducirse la etiqueta \n al comienzo de la línea de caracteres de cada línea.

15.2.3 paste

La función paste permite concatenar todos sus argumentos como una cadena de caracteres que puede asignarse a un objeto para traspasarlo luego como argumento a alguna otra función.

Considérese una situación en la que, al interior de una función se tengan los siguientes argumentos:

confianza <- 95
method <- "Tukey"

Supóngase ahora que se desea construir el título para un gráfico, a partir de la concatenación de los anteriores argumentos con cadenas de texto predefinidas.

La siguiente instrucción ilustra cómo concatenar los diferentes elementos y guardarlos en un objeto (título en el presente ejemplo), que podría invocarse posteriormente.

título <- paste("Intervalo de confianza del", confianza, "% basado en el método",
                method)

El contenido del vector título se visualiza así:

cat(título)
Intervalo de confianza del 95 % basado en el método Tukey
cat + paste

La función paste no tiene asociado un método de impresión. Consecuentemente, debe usarse cat para enviar a consola —de manera limpia— el contenido de los objetos generados por paste.

Constrástese esta presentación con la que genera la función print:

print(título)
[1] "Intervalo de confianza del 95 % basado en el método Tukey"

El objeto generado por la función paste es un vector tipo character, en el que sus diferentes argumentos quedan separados por defecto con un espacio. Es posible definir otro separador (o ninguno) mediante el argumento sep. Asimismo, puede usarse la función paste0, que concatena todos sus argumentos sin dejar espacio entre estos.

Cuando se usan argumentos de longitud mayor que 1, la función paste combina sus diferentes elementos.

Considérense los siguientes vectores:

nombres <- c("Eve", "Bryan", "Stiven", "Sara")
puntajes <- c(29, 18, 25, 27)

Cuando se concatenan usando cat, se presentan todos los elementos del primer argumento y seguidamente todos los del segundo, así:

cat(nombres, puntajes, sep=", ")
Eve, Bryan, Stiven, Sara, 29, 18, 25, 27

En contraste, cuando se concatenan mediante paste, se combinan elemento a elemento, así:

cat(paste(nombres, puntajes, sep=", "))
Eve, 29 Bryan, 18 Stiven, 25 Sara, 27

Nótese que el argumento sep actúa de diferente en cat y en paste.

El argumento sep en cat define el separador de todos los subelementos de los argumentos.

El argumento sep en paste define el separador de los subelementos de los diferentes argumentos, pero no se usa para separar los elementos combinados.

Es posible, sin embargo, usar el argumento collapse (inexistente en cat) para definir el separador entre los elementos combinados provenientes de diferentes argumentos, así:

cat(paste(nombres, puntajes, sep=", ", collapse ="; "))
Eve, 29; Bryan, 18; Stiven, 25; Sara, 27

Cuando alguno de los argumentos de la función paste es de tamaño mayor que 1, los elementos de los demás argumentos, se reciclan, de ser necesario (cf. sección 9.4), así:

cat(paste("Valores: ", nombres, puntajes, sep=", ", collapse ="; "))
Valores: , Eve, 29; Valores: , Bryan, 18; Valores: , Stiven, 25; Valores: , Sara, 27

Un resultado como este probablemente no corresponda con lo deseado. Para evitar que esto suceda, se combinan las funciones cat y paste, así:

cat("Valores:", paste(nombres, puntajes, sep=", ", collapse ="; "))
Valores: Eve, 29; Bryan, 18; Stiven, 25; Sara, 27

Si la cadena de caracteres resultante fuera a mostrarse en consola, esta se adaptaría automáticamente al ancho de la ventana, ocupando las líneas que fueran necesarias. No obstante, la partición de la cadena de caracteres podría realizarse por cualquier sitio, sin tener en cuenta la separación natural entre palabras, lo que podría dar lugar a textos poco estéticos.

Las funciones que se presentan en la sección 15.2.4 permiten ejercer un mejor control sobre el ancho máximo de la salidas y las particiones de las cadenas de caracteres.

15.2.4 strwrap y WriteLines

Para manejar cadenas de texto muy largas —que incluso puedan estar conformadas por varios párrafos— deben combinarse 1as funciones strwrap y WriteLines.

La función strwrap formatea grandes cadenas de caracteres que se despliegan en varias líneas, de manera que cada línea no exceda un ancho predeterminado y los saltos de línea se apliquen únicamente entre palabras. La impresión del texto formateado se realiza mediante la función WriteLines.

A continuación se reproduce de manera comentada y ligeramente modificada el ejemplo que aparece en las ayudas de la función strwrap.

Partamos del documento THANKS, que está ubicado en la carpeta doc, dentro de la ruta de instalación de R. Este documento —que puede visualizarse aquí (o en el bloc de notas)— consta de 14 párrafos.

¿¡Ruta de instalación!?

Averigüe cuál es ruta de instalación de R en su equipo, mediante la siguiente instrucción:

R.home()
“¿Qué vamos a hacer?

A continuación se resume el ejercicio que se realizará seguidamente.

Se importa a R el contenido de THANKS, se formatea adecuadamente, se extraen los últimos 4 párrafos y se envían al dispositivo de salida con un ancho máximo de 40 caracteres.

Para ello se realizan los siguientes pasos:

  1. Se usa la función readLines para importar —línea por línea— el contenido de THANKS.

  2. Mediante la función paste se concatenan todas las líneas en una única cadena de caracteres, manteniendo los marcadores de cambio de párrafo.

  3. Se utiliza la función strsplit para fraccionar la información en párrafos.

  4. Se convierte el objeto contendedor en un vector y se dejan únicamente los últimos 4 párrafos.

  5. Se usa nuevamente la función paste para concatenar la información de los 4 párrafos de interés.

  6. Se usa la función strwrap para definir el ancho máximo de las líneas, y la función WriteLines para la impresión.

Aunque este proceso pueda parecer un tanto engorroso, se considera una buena oportunidad para ilustrar el uso de algunas de las funciones más útiles para manejo de texto.

En tal sentido, más allá de presentar el resultado que aparece al final de esta sección (que podría obtenerse con una pocas líneas de código), se invita a revisar la manera en la que va reformateándose el texto a lo largo del proceso.

Inicialmente se usa la función readLines para importar a R el contenido de THANKS:

x <- readLines(file.path(R.home("doc"), "THANKS"))

La función readLines lee cada una de las líneas del archivo THANKS (78 líneas en total, incluyendo las líneas de blanco que separan los párrafos). Cada una de las líneas es almacenada como un elemento de un vector tipo character. Consecuentemente, el vector x es de tamaño 78.

¡Échele un vistazo!

Para visualizar la manera en la que se estructura el vector x, se envía su contenido a consola mediante la función print:

print(x)
 [1] "R would not be what it is today without the invaluable help of these"    
 [2] "people outside of the (former and current) R Core team, who"             
 [3] "contributed by donating code, bug fixes and documentation:"              
 [4] ""                                                                        
 [5] "Valerio Aimale, Suharto Anggono, Thomas Baier, Gabe Becker, Henrik"      
 [6] "Bengtsson, Roger Bivand, Ben Bolker, David Brahm, G\"oran Brostr\"om,"   
 [7] "Patrick Burns, Vince Carey, Saikat DebRoy, Matt Dowle, Brian D'Urso,"    
 [8] "Lyndon Drake, Dirk Eddelbuettel, Claus Ekstrom, Sebastian"               
 [9] "Fischmeister, John Fox, Paul Gilbert, Yu Gong, Gabor Grothendieck,"      
[10] "Frank E Harrell Jr, Peter M. Haverty, Torsten Hothorn, Robert King,"     
[11] "Kjetil Kjernsmo, Roger Koenker, Philippe Lambert, Jan de Leeuw, Jim"     
[12] "Lindsey, Patrick Lindsey, Catherine Loader, Gordon Maclean, Arni"        
[13] "Magnusson, John Maindonald, David Meyer, Ei-ji Nakama, Jens"             
[14] "Oehlschl\"agel, Steve Oncley, Richard O'Keefe, Hubert Palme, Roger"      
[15] "D. Peng, Jose' C. Pinheiro, Tony Plate, Anthony Rossini, Jonathan"       
[16] "Rougier, Petr Savicky, Guenther Sawitzki, Marc Schwartz, Arun"           
[17] "Srinivasan, Detlef Steuer, Bill Simpson, Gordon Smyth, Adrian"           
[18] "Trapletti, Terry Therneau, Rolf Turner, Bill Venables, Gregory"          
[19] "R. Warnes, Andreas Weingessel, Morten Welinder, James Wettenhall,"       
[20] "Simon Wood, and Achim Zeileis."                                          
[21] ""                                                                        
[22] "Others have written code that has been adopted by R and is"              
[23] "acknowledged in the code files, including"                               
[24] ""                                                                        
[25] "J. D. Beasley, David J. Best, Richard Brent, Kevin Buhr, Michael"        
[26] "A. Covington, Bill Cleveland, Robert Cleveland, G. W. Cran,"             
[27] "C. G. Ding, Ulrich Drepper, Paul Eggert, J. O. Evans, David M. Gay,"     
[28] "H. Frick, G. W. Hill, Richard H. Jones, Eric Grosse, Shelby Haberman,"   
[29] "Bruno Haible, John Hartigan, Andrew Harvey, Trevor Hastie, Min Long"     
[30] "Lam, George Marsaglia, K. J. Martin, Gordon Matzigkeit,"                 
[31] "C. R. Mckenzie, Jean McRae, Cyrus Mehta, Fionn Murtagh, John C. Nash,"   
[32] "Finbarr O'Sullivan, R. E. Odeh, William Patefield, Nitin Patel, Alan"    
[33] "Richardson, D. E. Roberts, Patrick Royston, Russell Lenth, Ming-Jen"     
[34] "Shyu, Richard C. Singleton, S. G. Springer, Supoj Sutanthavibul, Irma"   
[35] "Terpenning, G. E. Thomas, Rob Tibshirani, Wai Wan Tsang, Berwin"         
[36] "Turlach, Gary V. Vaughan, Michael Wichura, Jingbo Wang, M. A. Wong,"     
[37] "and the Free Software Foundation (for autoconf code and utilities)."     
[38] "See also files under src/extras."                                        
[39] ""                                                                        
[40] "Many more, too numerous to mention here, have contributed by sending bug"
[41] "reports and suggesting various improvements."                            
[42] ""                                                                        
[43] "Simon Davies whilst at the University of Auckland wrote the original"    
[44] "version of glm()."                                                       
[45] ""                                                                        
[46] "Julian Harris and Wing Kwong (Tiki) Wan whilst at the University of"     
[47] "Auckland assisted Ross Ihaka with the original Macintosh port."          
[48] ""                                                                        
[49] "R was inspired by the S environment which has been principally"          
[50] "developed by John Chambers, with substantial input from Douglas Bates,"  
[51] "Rick Becker, Bill Cleveland, Trevor Hastie, Daryl Pregibon and"          
[52] "Allan Wilks."                                                            
[53] ""                                                                        
[54] "A special debt is owed to John Chambers who has graciously contributed"  
[55] "advice and encouragement in the early days of R and later became a"      
[56] "member of the core team."                                                
[57] ""                                                                        
[58] "Stefano Iacus (up to 2014, a former member of R Core) and Simon"         
[59] "Urbanek developed the macOS port, including the R.app GUI, toolchains"   
[60] "and packaging."                                                          
[61] ""                                                                        
[62] "The Windows port was originally developed by Guido Masarotto (for a"     
[63] "while a member of R Core) and Brian Ripley, then further by Duncan"      
[64] "Murdoch (a former member of R Core) and then Jeroen Ooms (base) and"     
[65] "Uwe Ligges (packages).  Tomas Kalibera is the current main developer"    
[66] "of the Windows port and provides assistance with package porting."       
[67] ""                                                                        
[68] "Tomas Kalibera's work has been sponsored by Jan Vitek and funded by"     
[69] "his European Research Council grant \"Evolving Language Ecosystems"      
[70] "(ELE)\"."                                                                
[71] ""                                                                        
[72] "Computing support (including hardware, hosting and infrastructure) has"  
[73] "been provided/funded by the R Foundation, employers of R-Core members"   
[74] "(notably WU Wien, ETH Zurich, U Oxford and U Iowa) and by Northeastern"  
[75] "University and the University of Kent."                                  
[76] ""                                                                        
[77] "Distributions of R contain the recommended packages, whose"              
[78] "authors/contributors are listed in their DESCRIPTION files."             

Aunque la salida generada no se corresponde con lo que sería deseable para desplegar en consola un texto de estas características, ayuda a entender la forma en la que se organizan los contenidos importados mediante readLines.

A continuación se usa la función paste para concatenar los 78 elementos del vector x (las 78 líneas) en una única cadena de caracteres.

x <- paste(x, collapse = "\n")

El argumento collapse indica que deben colapsarse los 78 elementos del vector original en un solo elemento. Consecuentemente, el nuevo vector x es de tamaño 1.

Puede parecer extraño que un vector que recoja toda la información del archivo THANKS sea de tamaño 1. Sin embargo, lo único que esto indica es la manera en la que se almacena la información: en lugar de estar almacenada línea por línea (78 elementos), se almacena en una única cadena de caracteres (1 elemento). La función nchar permite averiguar el número de caracteres que conforman la cadena.

nchar(x)
[1] 3912

El uso del valor "\n" para el argumento collapse introduce un marcador \n entre líneas. Y puesto que entre párrafos hay un espacio vacío, se introduce un marcador doble \n\n entre párrafos.

¡Vuelva y mire!

Para visualizar la manera en la que se han colapsado las diferentes líneas del vector original y los marcadores que se introducen entre líneas y entre párrafos, envíe a consola el contenido del vector x:

print(x)

Para tener una versión un tanto más legible, envíe a consola el contenido de x, usando la función cat:

cat(x)

Aunque la visualización del contenido de x generada por cat es más legible que la que genera print, sigue adoleciendo del problema de la partición anárquica de la cadena de caracteres al final de la línea, cuando el ancho del dispositivo de salida es menor que el de la línea. Compruébelo reduciendo el ancho de la consola.

A continuación se utiliza la función strsplit para fraccionar la información en párrafos. El valor del argumento split indica los puntos por los que debe realizarse la partición; en el presente ejemplo, la partición se realiza donde se encuentren dos saltos de línea seguidos:

x <- strsplit(x, split = "\n\n")

La función strsplit genera una lista. Por tanto, x es una lista de tamaño 1, cuyo único elemento es un vector tipo character con 14 elementos: un elemento por párrafo.

¡Siga mirando!

Se envía el contenido de la lista x a consola para observar cómo se va organizando la información:

print(x)
[[1]]
 [1] "R would not be what it is today without the invaluable help of these\npeople outside of the (former and current) R Core team, who\ncontributed by donating code, bug fixes and documentation:"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
 [2] "Valerio Aimale, Suharto Anggono, Thomas Baier, Gabe Becker, Henrik\nBengtsson, Roger Bivand, Ben Bolker, David Brahm, G\"oran Brostr\"om,\nPatrick Burns, Vince Carey, Saikat DebRoy, Matt Dowle, Brian D'Urso,\nLyndon Drake, Dirk Eddelbuettel, Claus Ekstrom, Sebastian\nFischmeister, John Fox, Paul Gilbert, Yu Gong, Gabor Grothendieck,\nFrank E Harrell Jr, Peter M. Haverty, Torsten Hothorn, Robert King,\nKjetil Kjernsmo, Roger Koenker, Philippe Lambert, Jan de Leeuw, Jim\nLindsey, Patrick Lindsey, Catherine Loader, Gordon Maclean, Arni\nMagnusson, John Maindonald, David Meyer, Ei-ji Nakama, Jens\nOehlschl\"agel, Steve Oncley, Richard O'Keefe, Hubert Palme, Roger\nD. Peng, Jose' C. Pinheiro, Tony Plate, Anthony Rossini, Jonathan\nRougier, Petr Savicky, Guenther Sawitzki, Marc Schwartz, Arun\nSrinivasan, Detlef Steuer, Bill Simpson, Gordon Smyth, Adrian\nTrapletti, Terry Therneau, Rolf Turner, Bill Venables, Gregory\nR. Warnes, Andreas Weingessel, Morten Welinder, James Wettenhall,\nSimon Wood, and Achim Zeileis."
 [3] "Others have written code that has been adopted by R and is\nacknowledged in the code files, including"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
 [4] "J. D. Beasley, David J. Best, Richard Brent, Kevin Buhr, Michael\nA. Covington, Bill Cleveland, Robert Cleveland, G. W. Cran,\nC. G. Ding, Ulrich Drepper, Paul Eggert, J. O. Evans, David M. Gay,\nH. Frick, G. W. Hill, Richard H. Jones, Eric Grosse, Shelby Haberman,\nBruno Haible, John Hartigan, Andrew Harvey, Trevor Hastie, Min Long\nLam, George Marsaglia, K. J. Martin, Gordon Matzigkeit,\nC. R. Mckenzie, Jean McRae, Cyrus Mehta, Fionn Murtagh, John C. Nash,\nFinbarr O'Sullivan, R. E. Odeh, William Patefield, Nitin Patel, Alan\nRichardson, D. E. Roberts, Patrick Royston, Russell Lenth, Ming-Jen\nShyu, Richard C. Singleton, S. G. Springer, Supoj Sutanthavibul, Irma\nTerpenning, G. E. Thomas, Rob Tibshirani, Wai Wan Tsang, Berwin\nTurlach, Gary V. Vaughan, Michael Wichura, Jingbo Wang, M. A. Wong,\nand the Free Software Foundation (for autoconf code and utilities).\nSee also files under src/extras."                                                                                                                  
 [5] "Many more, too numerous to mention here, have contributed by sending bug\nreports and suggesting various improvements."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
 [6] "Simon Davies whilst at the University of Auckland wrote the original\nversion of glm()."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
 [7] "Julian Harris and Wing Kwong (Tiki) Wan whilst at the University of\nAuckland assisted Ross Ihaka with the original Macintosh port."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
 [8] "R was inspired by the S environment which has been principally\ndeveloped by John Chambers, with substantial input from Douglas Bates,\nRick Becker, Bill Cleveland, Trevor Hastie, Daryl Pregibon and\nAllan Wilks."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
 [9] "A special debt is owed to John Chambers who has graciously contributed\nadvice and encouragement in the early days of R and later became a\nmember of the core team."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
[10] "Stefano Iacus (up to 2014, a former member of R Core) and Simon\nUrbanek developed the macOS port, including the R.app GUI, toolchains\nand packaging."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
[11] "The Windows port was originally developed by Guido Masarotto (for a\nwhile a member of R Core) and Brian Ripley, then further by Duncan\nMurdoch (a former member of R Core) and then Jeroen Ooms (base) and\nUwe Ligges (packages).  Tomas Kalibera is the current main developer\nof the Windows port and provides assistance with package porting."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
[12] "Tomas Kalibera's work has been sponsored by Jan Vitek and funded by\nhis European Research Council grant \"Evolving Language Ecosystems\n(ELE)\"."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
[13] "Computing support (including hardware, hosting and infrastructure) has\nbeen provided/funded by the R Foundation, employers of R-Core members\n(notably WU Wien, ETH Zurich, U Oxford and U Iowa) and by Northeastern\nUniversity and the University of Kent."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
[14] "Distributions of R contain the recommended packages, whose\nauthors/contributors are listed in their DESCRIPTION files."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
¡Podría haber sido más complejo!

La función strsplit permite particionar los elementos de un vector de caracteres en subelementos, con base en una expresión regular que se usa como valor del argumento split.

Por la forma en la que está escrito el documento THANKS, puede usarse la expresión regular \n\n para separar párrafos. No obstante, en el ejemplo original de la función strwrap aparece una expresión regular más compleja: split = "\n[ \t\n]*\n".

Desglosémosla para ver lo que representa cada uno de estos elementos:

  1. \n representa un salto de línea al inicio.
  2. Los corchetes [] representan una clase de caracteres. Se buscará todo lo que representen las expresiones al interior de los corchetes. Dentro de esta clase se tiene:
    • Espacio \(\,\) (aparece al comienzo de la clase)
    • Tabulación horizontal \t
    • Salto de línea \n
  3. El asterisco * indica que los elementos dentro de la clase pueden aparecer una o más veces.
  4. Un salto de línea adicional que aparece al final \n

Luego, la expresión regular \n[ \t\n]*\n es mucho más general. Mediante esta se busca un salto de línea al comienzo y un salto de línea al final, con la posibilidad de que entre estos dos saltos de línea pueda haber espacios, tabuladores y saltos de línea adicionales, en cualquier número y orden.

Este expresión permitiría realizar partición por párrafos en documentos que no tuvieran un formato tan limpio como el de THANKS.

Para poder enviar la información contenida en x a la función de impresión writeLines es necesario extraerla como un vector.

Esto puede realizarse con cualquiera de las siguientes instrucciones:

x <- unlist(x)
x <- x[[1]]
x <- as.vector(x)
¡Una última mirada!

Al extraer x como vector, se mantiene la información de los diferentes párrafos separada en cada uno de los elementos del vector. La única diferencia con la lista es que el vector no está anidado dentro de un contenedor mayor.

Para visualizar la estructura del vector x se usa la función print:

print(x)
 [1] "R would not be what it is today without the invaluable help of these\npeople outside of the (former and current) R Core team, who\ncontributed by donating code, bug fixes and documentation:"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
 [2] "Valerio Aimale, Suharto Anggono, Thomas Baier, Gabe Becker, Henrik\nBengtsson, Roger Bivand, Ben Bolker, David Brahm, G\"oran Brostr\"om,\nPatrick Burns, Vince Carey, Saikat DebRoy, Matt Dowle, Brian D'Urso,\nLyndon Drake, Dirk Eddelbuettel, Claus Ekstrom, Sebastian\nFischmeister, John Fox, Paul Gilbert, Yu Gong, Gabor Grothendieck,\nFrank E Harrell Jr, Peter M. Haverty, Torsten Hothorn, Robert King,\nKjetil Kjernsmo, Roger Koenker, Philippe Lambert, Jan de Leeuw, Jim\nLindsey, Patrick Lindsey, Catherine Loader, Gordon Maclean, Arni\nMagnusson, John Maindonald, David Meyer, Ei-ji Nakama, Jens\nOehlschl\"agel, Steve Oncley, Richard O'Keefe, Hubert Palme, Roger\nD. Peng, Jose' C. Pinheiro, Tony Plate, Anthony Rossini, Jonathan\nRougier, Petr Savicky, Guenther Sawitzki, Marc Schwartz, Arun\nSrinivasan, Detlef Steuer, Bill Simpson, Gordon Smyth, Adrian\nTrapletti, Terry Therneau, Rolf Turner, Bill Venables, Gregory\nR. Warnes, Andreas Weingessel, Morten Welinder, James Wettenhall,\nSimon Wood, and Achim Zeileis."
 [3] "Others have written code that has been adopted by R and is\nacknowledged in the code files, including"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
 [4] "J. D. Beasley, David J. Best, Richard Brent, Kevin Buhr, Michael\nA. Covington, Bill Cleveland, Robert Cleveland, G. W. Cran,\nC. G. Ding, Ulrich Drepper, Paul Eggert, J. O. Evans, David M. Gay,\nH. Frick, G. W. Hill, Richard H. Jones, Eric Grosse, Shelby Haberman,\nBruno Haible, John Hartigan, Andrew Harvey, Trevor Hastie, Min Long\nLam, George Marsaglia, K. J. Martin, Gordon Matzigkeit,\nC. R. Mckenzie, Jean McRae, Cyrus Mehta, Fionn Murtagh, John C. Nash,\nFinbarr O'Sullivan, R. E. Odeh, William Patefield, Nitin Patel, Alan\nRichardson, D. E. Roberts, Patrick Royston, Russell Lenth, Ming-Jen\nShyu, Richard C. Singleton, S. G. Springer, Supoj Sutanthavibul, Irma\nTerpenning, G. E. Thomas, Rob Tibshirani, Wai Wan Tsang, Berwin\nTurlach, Gary V. Vaughan, Michael Wichura, Jingbo Wang, M. A. Wong,\nand the Free Software Foundation (for autoconf code and utilities).\nSee also files under src/extras."                                                                                                                  
 [5] "Many more, too numerous to mention here, have contributed by sending bug\nreports and suggesting various improvements."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
 [6] "Simon Davies whilst at the University of Auckland wrote the original\nversion of glm()."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
 [7] "Julian Harris and Wing Kwong (Tiki) Wan whilst at the University of\nAuckland assisted Ross Ihaka with the original Macintosh port."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
 [8] "R was inspired by the S environment which has been principally\ndeveloped by John Chambers, with substantial input from Douglas Bates,\nRick Becker, Bill Cleveland, Trevor Hastie, Daryl Pregibon and\nAllan Wilks."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
 [9] "A special debt is owed to John Chambers who has graciously contributed\nadvice and encouragement in the early days of R and later became a\nmember of the core team."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
[10] "Stefano Iacus (up to 2014, a former member of R Core) and Simon\nUrbanek developed the macOS port, including the R.app GUI, toolchains\nand packaging."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
[11] "The Windows port was originally developed by Guido Masarotto (for a\nwhile a member of R Core) and Brian Ripley, then further by Duncan\nMurdoch (a former member of R Core) and then Jeroen Ooms (base) and\nUwe Ligges (packages).  Tomas Kalibera is the current main developer\nof the Windows port and provides assistance with package porting."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
[12] "Tomas Kalibera's work has been sponsored by Jan Vitek and funded by\nhis European Research Council grant \"Evolving Language Ecosystems\n(ELE)\"."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
[13] "Computing support (including hardware, hosting and infrastructure) has\nbeen provided/funded by the R Foundation, employers of R-Core members\n(notably WU Wien, ETH Zurich, U Oxford and U Iowa) and by Northeastern\nUniversity and the University of Kent."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
[14] "Distributions of R contain the recommended packages, whose\nauthors/contributors are listed in their DESCRIPTION files."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

Con el fin de simplificar la salida final, eliminaremos los primeros 10 párrafos, con lo cual quedarán únicamente los últimos 4:

x <- x[-(1:10)]

Finalmente, antes de enviar el contenido del vector x al dispositivo de impresión, se usa paste para concatenar los párrafos en un vector de un único elemento, manteniendo el marcador \n\n para generar los saltos de párrafo.

x <- paste(x, collapse = "\n\n")

Hasta este punto todo lo que se ha hecho es leer y acondicionar una cadena de caracteres muy larga, manteniendo el marcador \n\n para generar los saltos de párrafo. Esta cadena de caracteres puede imprimirse, adecuadamente formateada, combinando las funciones strwrap y WriteLines.

Para imprimir los cuatro párrafos finales de THANKS, sin que se parta ninguna palabra y sin que ninguna línea de impresión exceda los 40 caracteres2, se usa la siguiente instrucción.

writeLines(strwrap(x, width = 40))
The Windows port was originally
developed by Guido Masarotto (for a
while a member of R Core) and Brian
Ripley, then further by Duncan Murdoch
(a former member of R Core) and then
Jeroen Ooms (base) and Uwe Ligges
(packages).  Tomas Kalibera is the
current main developer of the Windows
port and provides assistance with
package porting.

Tomas Kalibera's work has been
sponsored by Jan Vitek and funded by
his European Research Council grant
"Evolving Language Ecosystems (ELE)".

Computing support (including hardware,
hosting and infrastructure) has been
provided/funded by the R Foundation,
employers of R-Core members (notably WU
Wien, ETH Zurich, U Oxford and U Iowa)
and by Northeastern University and the
University of Kent.

Distributions of R contain the
recommended packages, whose
authors/contributors are listed in
their DESCRIPTION files.

15.2.5 c

La generación de títulos para gráficos constituye un caso de particular interés. Aunque las funciones de graficación normalmente incluyen un argumento para indicar el título, este se imprime en una sola línea, lo que puede ser poco estético si el título es muy largo.

En tales casos, puede usarse la función c para integrar elementos que deban imprimirse en diferentes líneas.

Puesto que la función c se ha usado exclusivamente para crear vectores cf. sección 8.1, resulta extraña su aparición en una sección dedicada a funciones especializadas para presentación de salidas. Y, en efecto, c no es una función especializada para dicho fin. Normalmente no se consideraría el uso de esta función para ningún aspecto relacionado con el formateo de salidas. Sin embargo, es la que resulta útil para este caso particular.

Considérese el título del gráfico que se genera mediante la función personalizada que se presenta en el capítulo 23. El título completo podría ser algo así como la siguiente cadena de caracteres:

Medias e intervalo de confianza del 95 % de Sepal.Length por nivel de Species usando la varianza individual dentro de cada grupo

Ahora, considérese el uso de c para generar un vector de caracteres que se use como valor del argumento main:

nombre.var <- 'Sepal.Length'
nombre.g <- 'Species'
main <- c(paste('Medias e intervalo de confianza del 95 % de', nombre.var),
          paste("por nivel de", nombre.g),
          'usando la varianza individual dentro de cada grupo')

En este caso, cada uno de los tres elementos del vector main se muestra centrado en una línea, tal y como se aprecia en el gráfico generado mediante el código 23.1.

En resumen…

Debe usarse la función print para imprimir el resultado de un objeto no atómico, respetando su estructura; en particular, si se trata de listas o data frames.

La función cat es la más adecuada para formatear texto que se envíe a la consola, siempre que no se requiera guardar dicho contenido.

La función paste (o paste0) es la más adecuada para formatear cadenas de caracteres, cuyo contenido deba guardarse para uso posterior. Se combina con cat para enviar el contenido a la consola.

Las funciones strwrap y WriteLines permiten formatear adecuadamente cadenas de caracteres de gran longitud, limitando el ancho máximo de cada línea y asegurando que no se parta ninguna palabra.

La función c permite controlar los saltos de línea en el título de un gráfico.

15.3 Escritura de datos en una hoja de cálculo

La función write_xlsx{writexl} permite extraer la información de un data frame y guardarla en una hoja de cálculo de Excel.

Considérese el siguiente código:

dfiris <- as.data.frame(iris)
writexl::write_xlsx(dfiris, "Iris.xlsx")

iris es una base de datos contenida en el paquete datasets3 (puede consultarse sobre su contenido mediante la instrucción ?iris).

La primera línea del código guarda la información de la base de datos iris en un data frame llamado dfiris (Normalmente se deseará exportar algún data frame generado como parte de algún proceso).

La segunda línea del código exporta el contenido del data frame dfiris (primer argumento de la función write_xlsx) a la hoja de cálculo Iris.xlsx (segundo argumento de la función write_xlsx).

El archivo Excel se escribe en el directorio de trabajo (cf. capítulo 3).

¡Las salidas aparecen incompletas!

Por defecto, R limita la cantidad de elementos que imprime a un máximo de 1000. Esto puede hacer que la salida en consola aparezca incompleta o truncada, especialmente al trabajar con objetos grandes.

Aunque este límite suele ser suficiente, en ciertos casos puede ser necesario aumentarlo. Para ello, se puede usar la siguiente instrucción:

options(max.print = 10000)

Esto incrementa el número máximo de elementos imprimibles en consola a 10 000.


  1. Aunque esto podría evitarse, incluyendo el argumento quote = FALSE.↩︎

  2. Esto permite visualizarla adecuadamente en la pantalla vertical de un teléfono celular. ¡Compruébelo!↩︎

  3. Este es uno de los 7 paquetes básicos de R (cf. capítulo 4)↩︎