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

Entre las funciones que permiten imprimir cadenas de caracteres o texto, se destacan print, cat, paste, strwrap y WriteLines. A continuación se detallan sus principales características.

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. Esto podría dar lugar a textos poco estéticos, por cuanto la partición de la cadena de caracteres no tendría en cuenta la separación natural entre palabras.

Para manejar cadenas de texto muy largas, que incluso puedan estar conformadas por varios párrafos, deben combinarse las funciones strwrap y WriteLines. La función strwrap sí tiene en cuenta los límites naturales entre palabras, pudiendo establecerse el ancho máximo de cada línea, mediante el argumento width. La impresión de las diferentes líneas resultantes se realiza mediante la función WriteLines.

A continuación, se presenta de manera resumida y comentada el ejemplo que aparece en las ayudas de la función strwrap.

Inicialmente se lee el archivo 'THANKS', que está ubicado en la carpeta “doc”, dentro de la ruta de instalación de R.

x <- paste(readLines(file.path(R.home("doc"), "THANKS")),
           collapse = "\n")

El objeto x es un vector de la clase character, de longitud 1, es decir que está conformado por una única cadena de caracteres (otra cosa es el número de caracteres contenidos en dicha cadena, lo cual puede verificarse con la función nchar).

A continuación, se fracciona la información en párrafos (este trabajo lo hace strsplit) y se eliminan los 10 primeros, dando por resultado un vector de la clase character con 4 elementos (cuatro párrafos).

x <- unlist(strsplit(x, "\n[ \t\n]*\n"))[-(1:10)]

Seguidamente, usando paste, se unen estos 4 párrafos en una única cadena de caracteres, manteniendo el marcador \n\n para representar 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 (864 caracteres), manteniendo un marcador para representar los saltos de párrafo (). Esta cadena de caracteres puede imprimirse, adecuadamente formateada, combinando las funciones strwrap y WriteLines.

Para imprimir los once párrafos en cuestión, sin que se parta ninguna palabra y sin que ninguna línea de impresión exceda los 50 caracteres, se usa la siguiente instrucción.

writeLines(strwrap(x, width = 50))
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.

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. La función c permite controlar los saltos de línea en el título de un gráfico. Las funciones strwrap y WriteLines permiten formatear adecuadamente cadenas de caracteres de gran longitud.

15.3 Escritura de datos en una hoja de cálculo

La función writexl::write_xlsx permite copiar data frames a una hoja de cálculo de Excel. Para tal efecto se usa la siguiente sintaxis:

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

Para este ejemplo, mediante la primera línea se asigna el contenido de iris al data frame dfiris2. El data frame que se desee exportar (en este caso, dfiris) se usa como primer argumento de la función write_xlsx para ser exportado a la hoja de cálculo “Iris.xlsx”.


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

  2. Normalmente, se deseará exportar algún data frame generado como parte de algún proceso.↩︎