Una de las grandes cualidades de un documento en formato R Markdown consiste en la posibilidad de incluir códigos de R, evaluarlos y, a su vez, insertar los resultados en un texto. Para ello es muy útil la paquetería knitr()de R, que cuenta con diversos comandos o scripts. Estos ayudar a ajustar la manera de evaluar e integrar tanto los códigos de R utilizados, así como sus resultados (ya sean en formato de valores numéricos, tablas de contenido o figuras y gráficas) en el documento de salida o output renderizado para el proceso de integración de los elementos de un documento de R Markdown.
En este documento se revisarán algunos de los comandos básicos de knitr() que permiten manipular y ajustar los comandos de R, bajo las necesidades del autor del documento al momento de construir e integra códigos y resultados en el documento de salida (output).
Para ello primero se revisarán comandos básicos para insertar y configurar de manera general en un documento en formato R Markdown, y posteriormente se revisarán elementos particulares para configurar a estos códigos tanto sobre su evaluación, presentación de los resultados, inserción de figuras y gráficas. Y también se revisarán comandos para la generación de tablas de contenido.
La creación de códigos de R para el análisis de datos y su posterior inserción en un documento de salida deseado (ya sea en formato .html, .pdf o .doc) se realiza a través de las secciones de trozos de código o chunks. Estos se diseñan iniciando con 3 acentos iniciales y 3 acentos finales, y en su interior se colocan corchetes en el que se indica el lenguaje del código, ```{r and }. En este caso el lenguaje es el mismo de R, y su estructura es:
```{r} #aquí se indica el lenguaje
paste("Hola", "Mundo") #este corresponde al código insertado
```
Esta estructura del chunk se puede escribir manualmente o también se puede insertar mediante el cursor dándole click izquierdo al botón de insert en la parte superior de la ventana de source. Otra manera de realizarlo es a través de la combinación de teclas: Ctrl + Alt + I (Cmd + Option + I en macOS).
El resultado del chunk es:
#Esto es un "chunk"
library(tidyverse) #Esto es un código de R
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.5 ✓ purrr 0.3.4
## ✓ tibble 3.1.6 ✓ dplyr 1.0.7
## ✓ tidyr 1.1.4 ✓ stringr 1.4.0
## ✓ readr 2.1.2 ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
Al renderizar el documento de R Markdown se observa que en el documento de salida, por defecto, los elementos que aparecen por defecto son:
Estos elementos se deben de “limpiar” al elaborar un reporte de investigación. En internet se puede encontrar una cantidad de elementos de apoyo, uno consiste en la página web de R Markdown elaborara por R Studio. También se cuenta con la hoja de apoyo o cheat sheet de R Markdown.
Finalmente, se recomienda el uso de la guía de referencia de R Markdown elaborada por R Studio.
A continuación se revisan algunos comandos para hacer dicha limpieza, empezando por las opciones para evaluar los códigos, configurar los resultados, inserción de gráficas y de tablas.
Además se utilizarán los datos de la encuesta correspondiente a la ola 2021 de Latinobarómetro
La evaluación de un código se refiere a si se desea que éste sea ejecutado, así como a si se desea que aparezca en impreso en el documento de salida.
El comando eval = puede adoptar dos valores: TRUE (por defecto) y FALSE. En el caso de señalar la última opción, entonces se indica que el código no sea ejecutado al momento de renderizar el documento R Markdown.
```{r eval=FALSE} #chunk configurado
mean(datoslb $ EDAD)
```
El resultado en el documento de salida solo consiste en presentar el código escrito pero no su resultado:
mean(datoslb $ EDAD)
El comando include = también puede adoptar dos valores posibles: TRUE (por defecto) o FALSE. En esta última opción lo que se indica es que el código sí sea ejecutado al momento de renderizar pero, a su vez, que el código mismo no sea incluido en el documento de salida.
```{r include=FALSE} #chunk configurado.
prom_edad <- mean(datoslb $ EDAD)
prom_edad
```
El resultado en el documento de salida no muestra el código ni el resultado en el documento de salida, pero sí se arroja el valor final en la venta de la consola y, aquí, también se guarda al objeto creado prom_edad:
La presentación de resultados de los códigos evaluados también se puede configurar mediante varios comandos.
collapse= puede adoptar dos valores posibles: TRUE o FALSE (por defecto). Este comando permite juntar los bloques de resultados para, así, ahorrar espacio.```{r collapse=TRUE} #chunk configurado.
prom_edad <- mean(datoslb $ EDAD)
prom_edad
```
El resultado es:
prom_edad <- mean(datoslb $ EDAD)
prom_edad
## [1] 40.56365
echo=, sus valores son TRUE(por defecto) y FALSE. Este último indica que no se deba imprimir el código en el documento de salida. Por ejemplo:```{r echo=FALSE} #chunk configurado.
prom_edad <- mean(datoslb $ EDAD)
prom_edad
```
El resultado es que no se imprimirá el código en el documento de salida, pero sí se evalúa el código.
## [1] 40.56365
results= puede adoptar 3 valores: hide, hold y asis. En el caso de hide no se muestran los resultados del código en el documento de salida. En el caso de hold se retrasa mostrar todos los resultados hasta el final del código. El argumento de asis separa los resultados sin re formatearlos.El comando hide:
```{r results=`hide`} #chunk configurado.
prom_edad <- mean(datoslb $ EDAD)
prom_edad
```
El resultado es:
prom_edad <- mean(datoslb $ EDAD)
prom_edad
El comando hold:
```{r results=`hide`} #chunk configurado.
prom_edad <- mean(datoslb $ EDAD)
prom_edad
sd_edad <- sd(datoslb $ EDAD)
sd_edad
```
El resultado es:
prom_edad <- mean(datoslb $ EDAD)
prom_edad
sd_edad <- sd(datoslb $ EDAD)
sd_edad
## [1] 40.56365
## [1] 16.52447
El comando asis:
```{r results='asis'} #chunk configurado.
prom_edad <- mean(datoslb $ EDAD)
prom_edad
sd_edad <- sd(datoslb $ EDAD)
sd_edad
```
El resultado es:
prom_edad <- mean(datoslb $ EDAD)
prom_edad
[1] 40.56365
sd_edad <- sd(datoslb $ EDAD)
sd_edad
[1] 16.52447
error= puede adoptar dos valores: TRUE y FALSE (por defecto). El valor de TRUE indica que sí se muestren los mensajes de error, en caso de que el código contenga algún problema en el diseño o su evaluación. Asimismo, se debe tomar en cuenta que cuando error=FALSE (por defecto), además de arrojar el mensaje de error en la consola, también se detendrá el proceso de renderización del documento de salida, mientras que el valor de error=TRUE sí permite la renderización del documento, y en el output se presenta dicho mensaje de error.```{r error=TRUE} #chunk configurado.
prom_edad <- mean(datoslb $ EDAD)
prom_EDAD #este código está mal escrito
```
El resultado es:
prom_edad <- mean(datoslb $ EDAD)
prom_EDAD #este código está mal escrito a propósito
## Error in eval(expr, envir, enclos): object 'prom_EDAD' not found
message= puede adoptar dos valores: TRUE (por defecto) y FALSE permite controlar la presentación de mensajes aclaratorios sobre la evaluación de los códigos. El valor de message=FALSE indica que no se mostrarán los mensajes adicionales generados por R.```{r message=FALSE} #chunk configurado.
library(tidyverse)
```
En el resultado se observa que no se arroja ningún mensaje del sistema sobre el proceso de instalación de tidyverse así como sus conflictos (véase la activación de tidyverse en el punto 2).
library(tidyverse)
warning= que puede adoptar dos valores: TRUE (por defecto) y FALSE, y este último permite indicarle al sistema que no se muestren las advertencias de posibles problemas en el documento de salida, tras la evaluación del código.```{r warning=FALSE} #chunk configurado.
library(tidyverse)
```
El resultado será que se anulan los mensajes de advertencias en el output:
library(tidyverse)
También se pueden insertar valores que son resultados de correr código de R en los renglones de texto para, así, no estar escribiendo dicho valores. Para ello se utiliza la estructura de r función(objeto).
Por ejemplo:
```
"El promedio de anchura de los pétalos fue de `r mean(iris $ Sepal.Width` pulgadas".
```
Donde el resultado es:
“El promedio de anchura de los pétalos fue de 3.0573333 pulgadas”.
En R Markdown es posible incluir ecuaciones algebráicas, que son elaboradas por el autor del documento. Para ello se utiliza el signo de moneda $ecuación$ para indicar el inicio y el final de la ecuación.
Existen dos maneras de insertar dichas ecuaciones, una puede ser dentro del mismo renglón del texto redactado y la otra es en un párrafo aparte al renglón en el que se escribe la ecuación.
Cuando se utiliza solo un signo $X=f(X)$, la ecuación se incluye dentro de la misma línea del texto, por ejemplo: \(X=f(X)\)
Cuando se utilizan dos signos de moneda tanto al inicio como al final $$X=f(X)$$ entonces la ecuación se incluye en un párrafo aparte y centrada, por ejemplo: \[X=f(X)\]
A su vez, se debe tomar en cuenta que la sintaxis de las ecuaciones sigue la propia del sistema LaTex, para ello se puede tomar como referencia la página de apoyo de ecuaciones WikiLatex o https://en.wikibooks.org/wiki/LaTeX/Mathematics
Otra opción para escribir ecuaciones consiste en importar el código de un modelo estadístico, y que este sea traducido con los símbolos LaTex para representar al código estadístico de R. Para ello se utiliza el paquete equatiomatic(), que permite traducir un modelo estadístico de R en texto de R Markdown, mediante el comando extract_eq(nombre_del_modelo) a extraer.
Si solo se desea que se extraiga la ecuación con sus letras algebráicas, se realiza de la siguiente manera:
data("mtcars") #carga de los datos
modelo <- lm(mpg ~ cyl + disp, mtcars) #diseño del modelo de regresión
equatiomatic::extract_eq(modelo) # mostrar el modelo estadístico
Donde el resultado será:
data("mtcars") #carga de los datos
modelo <- lm(mpg ~ cyl + disp, mtcars) #diseño del modelo de regresión
equatiomatic::extract_eq(modelo) # mostrar el modelo estadístico
\[ \operatorname{mpg} = \alpha + \beta_{1}(\operatorname{cyl}) + \beta_{2}(\operatorname{disp}) + \epsilon \]
En caso de desear que se incluyan los valores de los coeficientes del modelo, entonces se ejecutará el script:
# mostrar el valor de los coeficientes
equatiomatic::extract_eq(modelo, use_coefs = TRUE)
Donde el resultado será:
# mostrar el valor de los coeficientes
equatiomatic::extract_eq(modelo, use_coefs = TRUE)
\[ \operatorname{\widehat{mpg}} = 34.66 - 1.59(\operatorname{cyl}) - 0.02(\operatorname{disp}) \]
La manera de colocar todos los códigos utilizados en una obra dentro de una sección de apéndice, se utiliza el script ref.label y la función knitr::all_labels() de la siguiente manera en un “chunk”:
# Appendix: Tódos los códigos utilizados en el reporte
```{r ref.label=knitr::all_labels(), echo=TRUE, eval=FALSE} #chunk modificado
```
Esto arrojará completamente todos los códigos.
Pero si solo se desea que en el apéndice de códigos se incluyan códigos seleccionados, se deben realizar algunos procedimientos adicionales:
appendix = TRUE, de manera:```{r appendix = TRUE} #chunk modificado
```
ref.label = knitr::all_labels(appendix == TRUE) para llamar solo a los códigos previamente seleccionados.# Appendix: Tódos los códigos utilizados en el reporte
```{r ref.label = knitr::all_labels(appendix == TRUE), echo=TRUE, eval=FALSE} #chunk modificado
```
R Markdown permite el uso de diversos métodos para insertar imágenes dentro de un texto para, así, posteriormente renderizarlo. En el caso de usar la sintaxis de Markdown existe el comando  para insertar imágenes guardadas en el directorio de trabajo del usuario en su computadora.
También existe la opción para insertar imágenes de diversos tipo mediante el uso de los chunks, en el que se utiliza la paquetería knitr() y que permite “llamarlos” cuando, previamente, fueron generados mediante un código de R y guardados como objetos.
El comando utilizado para incluir imágenes que, previamente, fueron guardados como objetos en R es knitr :: include_graphics(imagen1), y se incluyen desde un chunk nuevo, de la siguiente manera:
imagen1 <- c("https://telos.fundaciontelefonica.com/wp-content/uploads/2019/04/telos-110-regulacion-partidos-politicos-privacidad-ilustracion-daniel-tornero.jpg") #importación de una imagen desde internet y se guarda como objeto.
knitr :: include_graphics(imagen1) #comando para insertar objeto/imagen en el documento de salida.
En caso de que se deseé “limpiar” el código para que solo se presente la imagen en el documento de salida, entonces se pueden utilizar varios argumentos, como: echo = FALSE, out.width = '20%', fig.align ='center' de la siguiente manera:
R Markdown también permite la inclusión de gráficos generados desde un mismo chunk, y de esta manera no es necesario generar el gráfico en una paquetería distinta, ni tampoco se debe guardar o copiar y pegar el gráfico dentro del procesador de texto (por ej. piénsese en los pasos que se deben realizar para generar un gráfico y pegarlo al momento de redactar un texto en el procesador de textos Word u otro parecido).
Para isertar una gráfica desde un data frame existente en el ambiente de trabajo de R Studio, primero se debe generar el código del gráfico deseado en un chunk, y posteriormente debe ser “llamado” dentro del mismo trozo de código. Al momento de renderizar dicho código, el documento de salida contendrá al gráfico elaborado.
Por ejemplo, a continuación se genera un boxplot mediante la paquetería ggplot() a partir del data frame data("iris") (disponible dentro de R Studio), y que será renderizado posteriormente.
library(tidyverse) #se carga la librería que contiene a ggplot
library(ggthemes) #se carga la librería para afinar los gráficos de ggplot
data("iris") #se carga el data frame
grafica1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) + #se crea el objeto y el lienzo del gráfico
geom_boxplot() + #se define el formato de salida de la gráfica, o la gráfica de caja
geom_jitter(aes(colour = Species), size = 3, alpha = 0.4) + #se incluyen un gráfico de dispersión para los datos
theme_minimal() #se define el estilo del gráfico
grafica1 #se llama al gráfico para que sea impreso
Ahora si se desea insertar la misma gráfica pero quitando el código, las advertencias y los mensajes para que, al final, solo se observe el resultado del código, centrado y de tamaño reducido, se utilizan las opciones de chunk siguientes: echo=FALSE, fig.align='center', message=FALSE, warning=FALSE, out.width='45%'.
Y el resultado producido es:
La inserción de tablas es un elemento importante para la presentación de una gran variedad de datos. En esta sección se revisarán algunas alternativas para insertar tablas de contenido generadas desde objetos previamente existentes en el ambiente de R y R Studio. Especialmente cuando se trabaja con objetos del tipo data frames. También se debe tener en cuenta que será importante reconocer el formato de salida del documento (.html, .pdf, .doc) a renderizar para, así, ubicar la forma en que será visualizado.
La librería kable() es un paquete que cuenta con buena integración con knitr(), y permite la generación de tablas. Pero se debe tener en cuenta que la primer condición para generar esta forma de presentación consiste en que los datos se encuentren en formato rectangular como tipo matriz o data frames. Otro elemento a tomar en consideración es que dicha paquetería no permite fusionar celdas.
La estructura del script de kable() es:
kable(x, format, digits = getOption("digits"), row.names = NA,
col.names = NA, align, caption = NULL, label = NULL,
format.args = list(), escape = TRUE, ...)
Insertar una tabla utilizando la libraría knitr() y el comando kable().
data("mtcars")
tabla1 <- head(mtcars) #vistazo a los primeros 6 casos o filas
knitr :: kable(tabla1,
caption = "Distribución de casos")
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
El formato de salida de la tabla de contenido puede ser modificado mediante el argumento format =, que define el tipo de resultado de la tabla que se genera y para ello acepta varios tipos de indicaciones, como: pipe(tabla donde los datos están separados por “barras”, valor por defecto), simple (tabla simple donde los valores están separados por espacios), latex (el resultado se arroja en redacción LaTex), html(el resultado se arroja en redacción html).
Por ejemplo:
Tabla en formato de pipe
knitr::kable(tabla1, "pipe")
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
Tabla en formato simple
knitr::kable(tabla1, "simple")
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
Tabla en formato html
knitr::kable(tabla1, "html")
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
Tabla en formato latex (Este no será visible en otro formato que no sea .pdf)
knitr::kable(tabla1, "latex")
Tabla en formato rst (barras horizontales)
knitr::kable(tabla1, "rst")
================= ==== === ==== === ==== ===== ===== === === ==== ==== mpg cyl disp hp drat wt qsec vs am gear carb ================= ==== === ==== === ==== ===== ===== === === ==== ==== Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 ================= ==== === ==== === ==== ===== ===== === === ==== ====
Para ello se utiliza el argumento col.names = y se incluye un vector con el nombre de las columnas en texto (entrecomillado). El número de nombres de columnas debe ser idéntico a las columnas incluidas en la tabla. Por ejemplo:
tabla2 <- head(iris)
knitr::kable(tabla2,
col.names = c('se', 'necesitan', 'cinco', 'nombres', 'aquí'))
| se | necesitan | cinco | nombres | aquí |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3.0 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5.0 | 3.6 | 1.4 | 0.2 | setosa |
| 5.4 | 3.9 | 1.7 | 0.4 | setosa |
Esto se especifica a partir del argumento align =, y los valores posibles son: l para izquierda, c para centrado, r para derecha.
También se puede generar una versión simplificada de alineamientos según el número de columnas: kable(..., align = c('c', 'l')), y esto es lo mismo que kable(..., align = 'cl'). Por ejemplo:
# left, center, center, right, right
knitr::kable(tabla2, align = "lccrr")
| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3.0 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5.0 | 3.6 | 1.4 | 0.2 | setosa |
| 5.4 | 3.9 | 1.7 | 0.4 | setosa |
Para ello se usa el argumento caption = "nombre de la tabla", de la siguiente manera:
knitr::kable(tabla2, caption = "Ejemplo de título de la tabla.")
| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3.0 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5.0 | 3.6 | 1.4 | 0.2 | setosa |
| 5.4 | 3.9 | 1.7 | 0.4 | setosa |
Se puede definir el número de decimales con el argumento digits = #
knitr::kable(tabla1,
digits = 1)
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 | 3.9 | 2.6 | 16.5 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 | 3.9 | 2.9 | 17.0 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108 | 93 | 3.9 | 2.3 | 18.6 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.1 | 3.2 | 19.4 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 | 3.1 | 3.4 | 17.0 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225 | 105 | 2.8 | 3.5 | 20.2 | 1 | 0 | 3 | 1 |
También se puede quitar la notación científica con el argumento format.args =, dentro del que se puede utilizar scientific = FALSE, así como añadir una coma a los números en miles con big.mark = ",")
knitr::kable(tabla1,
digits = 1,
format.args = list(big.mark = ",",
scientific = FALSE))
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 | 3.9 | 2.6 | 16.5 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 | 3.9 | 2.9 | 17.0 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108 | 93 | 3.9 | 2.3 | 18.6 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.1 | 3.2 | 19.4 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 | 3.1 | 3.4 | 17.0 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225 | 105 | 2.8 | 3.5 | 20.2 | 1 | 0 | 3 | 1 |
La paquetería kableExtra() permite realizar modificaciones especiales a tablas, para ello primero se debe instalar y activar dicha paquetería:
# instalar desde CRAN
install.packages("kableExtra")
Este paquete se puede utilizar complementariamente con el argumento de %>%(pipes de dplyr() dentro de tidyverse()).
A partir del argumento kable_styling(), se pueden modificar diversos aspectos de las tablas, y a continuación se revisarán algunos comandos.
Por ejemplo, se puede indicar la inclusión de sombreado en filas alternadas de la tabla con el argumento:
library(knitr)
library(kableExtra)
##
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
kable(head(iris)) %>%
kable_styling(latex_options = "striped")
| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3.0 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5.0 | 3.6 | 1.4 | 0.2 | setosa |
| 5.4 | 3.9 | 1.7 | 0.4 | setosa |
En caso que desear aplicar el estilo sombreado en un documento LaTex, en formato de salida .pdf, el argumento se debe modificar por latex_options = "striped".
Para ello se utiliza el argumento font_size = # dentro del argumento kable_styling().
kable(head(iris, 5), booktabs = TRUE) %>%
kable_styling(font_size = 8)
| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3.0 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5.0 | 3.6 | 1.4 | 0.2 | setosa |
Para ello se utilizan los argumentos row_spec() y column_spec() de la siguiente manera:
kable(head(iris, 5), align = 'c', booktabs = TRUE) %>% ##Aquí se definen los datos de la tabla
row_spec(1, bold = TRUE, italic = TRUE) %>% ##Aquí se define la primer fila, letra negritas e itálicas
row_spec(2:3, color = 'white', background = 'black') %>% ##Aquí se define la 2a y 3a fila, color de letras blancas, fondo negro
row_spec(4, underline = TRUE, monospace = TRUE) %>% ##Aquí se define la 4a fila, subrayado, cambio de letra
row_spec(5, angle = 45) %>% ##Aquí se define la 5a fila, letras en ángulo de 45 grados
column_spec(5, strikeout = TRUE) ##Aquí se define la 5a columna, tachado
| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3.0 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5.0 | 3.6 | 1.4 | 0.2 | setosa |
Los argumentos a utilizar son pack_rows() para agrupar filas, y add_header_above() para integrar varias columnas bajo un título en común.
Por ejemplo:
iris2 <- iris[1:5, c(1, 3, 2, 4, 5)]
kable(iris2, booktabs = TRUE) %>% ##Se crea la tabla y las columnas con datos
add_header_above(c("Largo" = 2, "Ancho" = 2, " " = 1)) %>% ##Se indica la creación de un encabezado que se llamará "Largo" y ocupa 2 columnas, otro encabezado que se llama "Ancho" y se extiende 2 columnas y un 3er encabezado con nombre "(vacío)" con extensión de 1 columna.
add_header_above(c("Medidas" = 4, "Más atributos" = 1)) ##Se añade un 3er encabezado, el primero se llama "Medidas" y se extiende por 4 columnas y el 2o se llama "Más atributos" y se extiende 1 columna
| Sepal.Length | Petal.Length | Sepal.Width | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 1.4 | 3.5 | 0.2 | setosa |
| 4.9 | 1.4 | 3.0 | 0.2 | setosa |
| 4.7 | 1.3 | 3.2 | 0.2 | setosa |
| 4.6 | 1.5 | 3.1 | 0.2 | setosa |
| 5.0 | 1.4 | 3.6 | 0.2 | setosa |
En el caso del argumento pack_rows(), funciona parecido a add_header_above(), donde para definir el número de filas que se agruparán se debe utilizar el argumento index, en donde se indica el título del agrupamiento así como su extensión definido en número de filas, de la siguiente manera:
iris3 <- iris[c(1:2, 51:54, 101:103), ] ##Se define el data frame filtrado por las filas
kable(iris3[, 1:4], booktabs = TRUE) %>% ##Se crea la tabla
pack_rows(index = c("setosa" = 2, "versicolor" = 4, "virginica" = 3) #Se define el nombre de agrupamiento de las filas así como el número de filas incluido en cada grupo
)
| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | |
|---|---|---|---|---|
| setosa | ||||
| 1 | 5.1 | 3.5 | 1.4 | 0.2 |
| 2 | 4.9 | 3.0 | 1.4 | 0.2 |
| versicolor | ||||
| 51 | 7.0 | 3.2 | 4.7 | 1.4 |
| 52 | 6.4 | 3.2 | 4.5 | 1.5 |
| 53 | 6.9 | 3.1 | 4.9 | 1.5 |
| 54 | 5.5 | 2.3 | 4.0 | 1.3 |
| virginica | ||||
| 101 | 6.3 | 3.3 | 6.0 | 2.5 |
| 102 | 5.8 | 2.7 | 5.1 | 1.9 |
| 103 | 7.1 | 3.0 | 5.9 | 2.1 |
Ajustar el tamaño de una tabla solo es aplicable en LaTex, para ello se usa la función kableExtra::landscape(), por ejemplo:
tab <- kable(tail(mtcars, 5), booktabs = TRUE)
tab # tabla original, muy ancha en LaTex
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Lotus Europa | 30.4 | 4 | 95.1 | 113 | 3.77 | 1.513 | 16.9 | 1 | 1 | 5 | 2 |
| Ford Pantera L | 15.8 | 8 | 351.0 | 264 | 4.22 | 3.170 | 14.5 | 0 | 1 | 5 | 4 |
| Ferrari Dino | 19.7 | 6 | 145.0 | 175 | 3.62 | 2.770 | 15.5 | 0 | 1 | 5 | 6 |
| Maserati Bora | 15.0 | 8 | 301.0 | 335 | 3.54 | 3.570 | 14.6 | 0 | 1 | 5 | 8 |
| Volvo 142E | 21.4 | 4 | 121.0 | 109 | 4.11 | 2.780 | 18.6 | 1 | 1 | 4 | 2 |
tab %>%
kable_styling(latex_options = "scale_down") ##Aquí se re escala la tabla en un formato de salida .pdf. Si esto se mira en .html no se nota ningún ajuste.
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Lotus Europa | 30.4 | 4 | 95.1 | 113 | 3.77 | 1.513 | 16.9 | 1 | 1 | 5 | 2 |
| Ford Pantera L | 15.8 | 8 | 351.0 | 264 | 4.22 | 3.170 | 14.5 | 0 | 1 | 5 | 4 |
| Ferrari Dino | 19.7 | 6 | 145.0 | 175 | 3.62 | 2.770 | 15.5 | 0 | 1 | 5 | 6 |
| Maserati Bora | 15.0 | 8 | 301.0 | 335 | 3.54 | 3.570 | 14.6 | 0 | 1 | 5 | 8 |
| Volvo 142E | 21.4 | 4 | 121.0 | 109 | 4.11 | 2.780 | 18.6 | 1 | 1 | 4 | 2 |
Otra alternativa para insertar tablas es mediante la paquetería de flextable dentro de otro chunk.
Esta paquetería también permite trabajar con un data frame, además que se integra con el comando de %>% (pipes), y cuenta con gran flexibilidad para modificar los espacios de las tablas según las necesidades del autor.
El comando básico para llamar la creación de una tabla desde un data frame es mediante el comando flextable(data.frame), por ejemplo:
library(flextable)
flextable(head(iris))
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.1 | 3.5 | 1.4 | 0.2 | setosa |
4.9 | 3.0 | 1.4 | 0.2 | setosa |
4.7 | 3.2 | 1.3 | 0.2 | setosa |
4.6 | 3.1 | 1.5 | 0.2 | setosa |
5.0 | 3.6 | 1.4 | 0.2 | setosa |
5.4 | 3.9 | 1.7 | 0.4 | setosa |
flextable()también se puede integrar con el uso de los %>% (pipes) de dplyr() al momento de “pasar” el data frame y, así, generar las tablas de contenido, de la siguiente manera:
tabla3<-head(iris) #aquí se crea un objeto
tabla3 %>% #se incluye un "pipe"
flextable() #se manda a llamar a la tabla de contenido
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.1 | 3.5 | 1.4 | 0.2 | setosa |
4.9 | 3.0 | 1.4 | 0.2 | setosa |
4.7 | 3.2 | 1.3 | 0.2 | setosa |
4.6 | 3.1 | 1.5 | 0.2 | setosa |
5.0 | 3.6 | 1.4 | 0.2 | setosa |
5.4 | 3.9 | 1.7 | 0.4 | setosa |
Afinando la tabla:
tabla3 %>%
flextable() %>%
fix_border_issues(part = "all") %>%
bold(part = "header") %>%
align(align = "center", part = "all") %>%
color(., ~ Sepal.Width > 3.5, ~ Sepal.Width, color = "red") %>%
color(., ~ Sepal.Length > 5, ~ Sepal.Length, color = "blue")
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.1 | 3.5 | 1.4 | 0.2 | setosa |
4.9 | 3.0 | 1.4 | 0.2 | setosa |
4.7 | 3.2 | 1.3 | 0.2 | setosa |
4.6 | 3.1 | 1.5 | 0.2 | setosa |
5.0 | 3.6 | 1.4 | 0.2 | setosa |
5.4 | 3.9 | 1.7 | 0.4 | setosa |
Afinando la presentación de la tabla:
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.1 | 3.5 | 1.4 | 0.2 | setosa |
4.9 | 3.0 | 1.4 | 0.2 | setosa |
4.7 | 3.2 | 1.3 | 0.2 | setosa |
4.6 | 3.1 | 1.5 | 0.2 | setosa |
5.0 | 3.6 | 1.4 | 0.2 | setosa |
5.4 | 3.9 | 1.7 | 0.4 | setosa |