Tablas en pdf con RMarkdown y Knitr

Para los que suelen trabajar con archivos Rmarkdown desde RStudio, hoy traemos tres funciones para generar tablas en un documento pdf: kable(), pandoc.table() y xtable(); de los paquetes: knitr, pander y xtable, respectivamente.

Pasamos a ver cada una por separado, generando las tablas con las opciones habituales en cada caso para que puedan servir de plantilla base.

Función kable(), del paquete knitr

Yo diría que la más sencilla de utilizar. Por defecto hace unas tablas muy bonitas. Tiene pocas opciones, así que, por un lado es muy fácil de aprender a usar pero, por otro, si queremos algo más concreto puede quedarse corta. Tal y como se afirma en si descripción: “No es su intención reemplazar a ningún otro paquete de R para hacer tablas”.

Una característica a destacar es que en un pdf, si quedara muy larga la tabla para una página, por defecto kable() la divide en dos y la continúa en la siguiente.

# install.packages("knitr")
library(knitr)
data("airquality")
df <- head(airquality, 15)
kable( df , caption = "BBDD `airquality` con `kable()`"
       , align = c('l', 'c', 'r', 'r', 'c', 'l')
       , col.names = c("Ozono","Solar.R","Viento","Temp","Mes","Día")
       , row.names = TRUE
       , digits = 1
       , format.args = list( decimal.mark = ",")
      )

tabla-kable

Función pandoc.table(), del paquete pander

Tiene bastantes opciones. Características a destacar: que también divide las tablas como kable() si son muy largas, y además, también lo hace si son muy anchas. En este último caso, te parte la tabla automáticamente y te la muestra a continuación con las columnas que no hubieran cabido. Importante: no hay que olvidar poner results = 'asis' en las opciones del chunk.

# install.packages("pander")
library(pander)
pandoc.table( df
              , caption = "BBDD `airquality` con `pandoc.table()`"
              , justify = 'lcrrcl'
              , round = 2
              , decimal.mark = ","
              , missing = NA
              , emphasize.rownames = FALSE
              , split.cells = 5
              , emphasize.strong.cells =
                  which(df > 12 & df == df$Wind, arr.ind = TRUE)
             )

tabla-pandoctable

Función xtable(), del paquete xtable

Potencia LaTeX. Lo mejor es utilizarla junto con print(), ya que, se añaden más opciones (ver print.xtable()). Importante: igual que con pandoc.table() hay que poner results = 'asis'.

# install.packages("xtable")
library(xtable)
print(xtable( df
             , caption = "BBDD \\texttt{airquality} con
                          \\texttt{xtable()}"
             , align = 'clcrrcp{2cm}'
             , digits = 2
             , label = "tab:label"
            )
      , comment = FALSE
      , table.placement = "h!"
      , caption.placement = "top"
      , NA.string = "NA"
     )

tabla-xtable

Conclusiones

En resumen, para una tabla sencilla en Rmd yo personalmente utilizo la función kable(): no hay que instalar ningún paquete adicional a knitr y la sintaxis se aprende muy rápido. Solo cuando quiero hacer alguna tabla más concreta (o cuando es muy ancha) opto por pandoc.table(), que te da muchas opciones sin perder la relativa sencillez. Y finalmente, en contadas situaciones, cuando he de hacer algo muy muy concreto en el que tengo que tirar de LaTeX utilizo xtable().

Cada cual que utilice la que más le guste, o como yo, la que más le convenga en cada caso.

Referencias y enlaces

12 Respuestas a “Tablas en pdf con RMarkdown y Knitr

  1. Muy interesante. Me gustaría saber cómo se consigue que salga “Cuadro 1” en lugar de “Table 1” cuando uso el pandoc.table

    • Hola, Jordi:
      Pues eso es tema del idioma del documento. Si estás en Rmd y haciendo un pdf, como utiliza LaTeX, tendrás que cambiarlo con las opciones de LaTeX, esto es, con \usepackage[spanish]{babel}.
      Para ponerlo en el YAML (la primera parte de opciones del Rmd) solo tienes que añadir la línea: header-includes: \usepackage[spanish]{babel}.
      Saludos
      Álvaro

  2. Buenos días,
    Le agradecería su ayuda en lo siguiente:

    Tengo algunos problemas para poder publicar con knitr en RStudio con salida .pdf

    He creado algunas figuras (histogramas y diagramas de caja y bigotes) pero no me salen (en el archvio pdf) en el orden en que los he puesto en el archivo .Rmd.

    Cuando creo una tabla (con kable) el nombre (fig.cap) me sale arriba, ¿cómo puede aparecer en la parte inferior de la tabla?.

    Gracias de antemano

    Eloy López

    • Hola, Eloy:

      Lo de que las figuras no aparezcan en orden es un comportamiento de LaTeX, que lo hace así para no dejar huecos si una figura cae justo entre dos páginas. Para forzar a que quede en el sitio puedes añadir knitr::opts_chunk$set(fig.pos = 'H'), al principio de tu documento.

      En las tablas lo recomendado es poner los caption arriba, por eso lo hace automáticamente. No sé si se podrá cambiar con alguna opción, la verdad.

      Saludos
      Álvaro

  3. Hola, quisiera que POR FAVOR me ayudaran con un problema que tengo al generar tablas en Rnw pues uso xtable pero este es bloqueado por un codigo que tengo para ajustar margenes

    \documentclass{article}
    \usepackage{listings}
    \usepackage{inconsolata}
    <<echo=FALSE>>=
    options(width=60)

    listing <- function(x, options) {
    paste("\\begin{lstlisting}[basicstyle=\\ttfamily,breaklines=true]\n",
    x, "\\end{lstlisting}\n", sep = "")
    }
    knit_hooks$set(source=listing, output=listing)
    @
    \begin{document}
    <>=

    set global chunk options

    opts_chunk$set(fig.path=’figure/minimal-‘, fig.align=’center’,
    fig.show=’markup’, warning=FALSE)
    options(replace.assign=TRUE,width=90)
    @

    Look at \ref{tab:mytable}.
    <<echo=FALSE,results=’asis’>>=
    library(xtable, car)
    print(xtable(x=mtcars[1:5,1:5], caption = “example”, label = “tab:mytable”))
    @

    <<background=’lavenderblush’>>=
    a<-matrix(c(“IntervalosDeEdad”,”Fecha.de.Inicio.de.Vigencia.de.la.Poliza”,”Fecha.de.Ocurrencia.del.Siniestro”,”intervalos”),ncol=2)
    @

    <<echo=FALSE,results=’asis’>>=
    print(xtable(a, caption = “example”, label = “tab:mytable”))
    @

    \end{document}

    .

    • Hola, Mayarin:

      Parece que eso ocurre porque no estás teniendo en cuenta el result=’asis’ y por, defecto, te introduce la tabla en un entorno kframe. Si lo tienes en cuenta y borras el krame funcionaría.

      Aquí te paso el código que tienes que añadir. El mejorarlo te lo dejo a ti.

      listing <- function(x, options) {
      paste("\begin{lstlisting}[basicstyle=\ttfamily,breaklines=true]\n",
      x, "\end{lstlisting}\n", sep = "")
      }

      listing2 <- function(x, options){
      if (options$results == 'asis' && !options$echo && options$fig.num == 0) {
      # remove all kframe's
      gsub('\\(begin|end)\{kframe\}', '', x)
      } else {
      paste("\begin{lstlisting}[basicstyle=\ttfamily,breaklines=true]\n",
      x, "\end{lstlisting}\n", sep = "")
      }
      }

      chunk <- function(x, options) {
      if (options$results == 'asis' && !options$echo && options$fig.num == 0) {
      # remove all kframe's
      gsub('\\(begin|end)\{kframe\}', '', x)
      } else x
      }

      knit_hooks$set(source = listing, output = listing2, chunk = chunk)

      Saludos
      Álvaro

  4. Buenas tardes,
    Tengo algún problema con el RMarkdown en RStudio.
    Estoy utilizando el comando \usepackage[spanish]{babel} y sin embargo no hace la indentación (sangrado) de los párrafos.
    Gracias de antemano por su ayuda,
    Eloy López

    • Buenas, Eloy:
      Eso viene definido por \parindent. En este enlace tienes más información.
      Saludos
      Álvaro

      • Gracias por la respuesta, Álvaro,
        Pero si estoy utilizando el paquete \usepackage[spanish]{babel} debía ponerme todos los párrafos sangrados, y si le añado el comando ‘es-noindentfirst’ debería sangrarme todos los párrafos menos el primero. Eso es lo que no consigo.
        De otra parte ¿como debo realizar la citas, utilizando los comandos de RMarkdown o los de latex?

        • Yo también entiendo que debería hacerlo, sí. Podrías probar a hacerte tu propia plantilla de LaTeX con lo mínimo y tirar de esa desde Rmarkdown, a lo mejor así sí funciona como debería.

          Pues como más te guste. Puedes especificar el bib poniendo bibliography en el YAML y luego utilizar [@id] o \ref{id}.

          Saludos
          Álvaro

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax