Creación programática de tablas de Markdown en R con KnitR


103

Estoy empezando a aprender sobre KnitR y el uso de Markdown para generar informes y documentos R. Esto parece perfecto para gran parte de los informes diarios que tengo que hacer con mi trabajo. Sin embargo, una cosa que no veo es una manera fácil de imprimir marcos de datos y tablas usando el formato Markdown (algo así como xtable, pero con Markdown en lugar de LaTeX o HTML). Sé que puedo incrustar la salida HTML de xtable, pero me preguntaba si había alguna solución basada en Markdown.


3
Considerando xtable y html .. Imprima código html con print(xtable(data), type = "html").
user974514

7
@TARehman Su pregunta me recordó que todavía no había una solución que produjera tablas directamente compatibles knitr, así que envié una solicitud de extracción panderpara agregar el estilo de la tabla. En futuras versiones de pander, debería poder hacerlopandoc.table(iris, style="rmarkdown")
Marius

1
@Marius ¿Sabes por qué pandoc no es parte de CRAN? ¿O cuándo podría formar parte de él? Sólo curioso.
TARehman

2
@TARehman No estoy muy seguro de si te refieres a pander o pandoc. panderdebería estar en CRAN. pandoc es un programa escrito en Haskell que convierte hacia y desde una amplia variedad de formatos diferentes, no es específico de R de ninguna manera.
Marius

1
Lo siento, quise decir pander, que no estaba en CRAN la última vez que escuché, no pandoc. Mi culpa. :)
TARehman

Respuestas:


122

Ahora knitr(desde la versión 1.3) el paquete incluye la kablefunción para crear tablas:

> library(knitr)
> kable(head(iris[,1:3]), format = "markdown")
|  Sepal.Length|  Sepal.Width|  Petal.Length|
|-------------:|------------:|-------------:|
|           5,1|          3,5|           1,4|
|           4,9|          3,0|           1,4|
|           4,7|          3,2|           1,3|
|           4,6|          3,1|           1,5|
|           5,0|          3,6|           1,4|
|           5,4|          3,9|           1,7|

ACTUALIZADO : si obtiene una rebaja sin formato en un documento, intente configurar la results = "asis"opción de fragmento.


24
cuando se ejecuta dentro de knitr, puede omitir el formatargumento, ya que knitr conoce el formato de salida y lo configurará automáticamente
Yihui Xie

3
@Yihui Eres increíble
isomorfismos

2
Intenté esto, pero `` {r} kable (...) solo muestra la rebaja en bruto
Alex Brown

6
Intente establecer la opción de fragmento local en results = asis.
Artem Klevtsov

5
FYI knitr ahora requiere el comando en el formatoresults = 'asis'
Stedy

32

Dos paquetes que harán esto son pander

library(devtools)
install_github('pander', 'Rapporter')

O ascii

pander es un enfoque ligeramente diferente para la construcción de informes (pero puede ser útil para esta función).

asciile permitirá printcon type = 'pandoc(o varios otros sabores de rebajas)

library(ascii)
print(ascii(head(iris[,1:3])), type = 'pandoc')



    **Sepal.Length**   **Sepal.Width**   **Petal.Length**  
--- ------------------ ----------------- ------------------
1   5.10               3.50              1.40              
2   4.90               3.00              1.40              
3   4.70               3.20              1.30              
4   4.60               3.10              1.50              
5   5.00               3.60              1.40              
6   5.40               3.90              1.70              
--- ------------------ ----------------- ------------------

Tenga en cuenta que en ambos casos, está dirigido a usar pandocpara convertir de markdown al tipo de documento deseado, sin embargo, el uso style='rmarkdown'creará tablas que son compatibles con este markdownpaquete y la conversión incorporada en rstudio.


3
Solo una nota sobre pander: puede producir las rmarkdowntablas con estilo también junto a otras, por ejemplo:pander(head(iris[,1:3]), style = 'rmarkdown')
daroczig

@daroczig - Gracias y anotado en la respuesta ahora,
mnel

26

Solo quería actualizar esto con lo que decidí hacer. Estoy usando el hwriterpaquete en este momento para imprimir tablas, y estoy usando las funciones row.*y col.*para poner clases CSS en diferentes elementos. Luego, escribí CSS personalizado para hacer mi pantalla como quería. Entonces, aquí hay un ejemplo en caso de que alguien más esté lidiando con algo similar.

Primero, cree un archivo que hará knittingy cambiará el Markdown a HTML:

FILE: file_knit.r
#!/usr/bin/env Rscript

library(knitr)
library(markdown)

knit("file.Rmd")
markdownToHTML("file.md","file.html",stylesheet="~/custom.css")

A continuación, cree el archivo de Markdown real:

FILE: file.Rmd
Report of Fruit vs. Animal Choices
==================================

This is a report of fruit vs. animal choices.

```{r echo=FALSE,results='asis'}
library(hwriter)
set.seed(9850104)
my.df <- data.frame(Var1=sample(x=c("Apple","Orange","Banana"),size=40,replace=TRUE),
                    Var2=sample(x=c("Dog","Cat","Bunny"),size=40,replace=TRUE))

tbl1 <- table(my.df$Var1,my.df$Var2)

tbl1 <- cbind(tbl1,rowSums(tbl1))
tbl1 <- rbind(tbl1,colSums(tbl1))

colnames(tbl1)[4] <- "TOTAL"
rownames(tbl1)[4] <- "TOTAL"

# Because I used results='asis' for this chunk, I can just use cat() and hwrite() to 
# write out the table in HTML. Using hwrite()'s row.* function, I can assign classes
# to the various table elements.
cat(hwrite(tbl1,
           border=NA,
           table.class="t1",
           row.class=list(c("header col_first","header col","header col","header col", "header col_last"),
                          c("col_first","col","col","col","col_last"),
                          c("col_first","col","col","col","col_last"),
                          c("col_first","col","col","col","col_last"),
                          c("footer col_first","footer col","footer col","footer col","footer col_last"))))
```

Finalmente, simplemente cree un archivo CSS personalizado.

FILE: custom.css
body {
  font-family: sans-serif;
  background-color: white;
  font-size: 12px;
  margin: 20px;
}

h1 {font-size:1.5em;}

table {
  border: solid;
  border-color: black;
  border-width: 2px;
  border-collapse: collapse;
  margin-bottom: 20px;
  text-align: center;
  padding: 0px;
}

.t1 .header {
  color: white;
  background-color: black;
  border-bottom: solid;
  border-color: black;
  border-width: 2px;
  font-weight: bold;
}

.t1 .footer {
  border-top: solid;
  border-color: black;
  border-width: 2px;
}

.t1 .col_first {
  border-right: solid;
  border-color: black;
  border-width: 2px;
  text-align: left;
  font-weight: bold;
  width: 75px;
}

.t1 .col {
  width: 50px;
}

.t1 .col_last {
  width: 50px;
  border-left: solid;
  border-color: black;
  border-width: 2px;
}

La ejecución ./file_knit.rme da file.html, que se ve así:

Salida de ejemplo

Así que, con suerte, esto podría ser útil para otros que quieran un poco más de formato en la salida de Markdown.


1
Sí, no. Funcionará con Markdown -> HTML pero no con Markdown -> PDF, Markdown -> DOCX ... La pregunta es sobre el uso de Markdown en general, no solo con el propósito de crear archivos HTML con él, podría haber sido su intención, pero no está escrito allí.
petermeissner

¿Notaste que estoy respondiendo mi propia pregunta? Puedo editar la pregunta o etiquetarla de manera diferente si crees que sería de ayuda.
TARehman

Por cierto, en el momento de esta respuesta, knitr solo admitía HTML. Es por eso que la pregunta no dice nada explícitamente sobre HTML.
TARehman

jip, cambiar la pregunta ayudaría ... pero ¿por qué hacerlo más específico cuando es de más utilidad para todos cuando es más amplio y más general? Con respecto a que responda su propia pregunta, los demás proporcionan tablas en formato Markdown, usted proporciona tablas en formato HTML; no está mal, pero las otras respuestas me parecen simplemente detalladas, elegantes y más útiles. no a todo el mundo le tiene que gustar tu respuesta, ¿no es suficiente que te haya gustado tu respuesta?
petermeissner

7
Tú mismo has dicho que mi respuesta no es incorrecta, pero que otras son mejores. La aplicación correcta del sistema de votación es votar a favor de las mejores respuestas, no en contra de la mía. Consulte también aquí: stackoverflow.com/help/privileges/vote-down "Utilice sus votos negativos cada vez que encuentre una publicación notoriamente descuidada, sin esfuerzo, o una respuesta que sea clara y quizás peligrosamente incorrecta".
TARehman

18

Hay funciones en el panderpaquete:

> library(pander)
> pandoc.table(head(iris)[, 1:3])

-------------------------------------------
 Sepal.Length   Sepal.Width   Petal.Length 
-------------- ------------- --------------
     5.1            3.5           1.4      

     4.9             3            1.4      

     4.7            3.2           1.3      

     4.6            3.1           1.5      

      5             3.6           1.4      

     5.4            3.9           1.7      
-------------------------------------------

4
Gracias por promocionar pander:) Tenga en cuenta que también puede utilizar el método S3 genérico para guardar algunos caracteres para escribir, como:pander(head(iris)[, 1:3])
daroczig

12

No es muy difícil crear su propia función personalizada. Aquí hay una prueba de concepto muy simple para generar una tabla rmarkdown de a data.frame:

   rmarkdownTable <- function(df){
      cat(paste(names(df), collapse = "|"))
      cat("\n")
      cat(paste(rep("-", ncol(df)), collapse = "|"))
      cat("\n")

      for(i in 1:nrow(df)){
        cat(paste(df[i,], collapse = "|"))
        cat("\n")
        }
    invisible(NULL)
    }

En el documento .Rmd, entonces usaría la función con results = 'asis':

```{r, results = 'asis'}
rmarkdownTable <- function(df){
  cat(paste(names(df), collapse = "|"))
  cat("\n")
  cat(paste(rep("-", ncol(df)), collapse = "|"))
  cat("\n")

  for(i in 1:nrow(df)){
    cat(paste(df[i,], collapse = "|"))
    cat("\n")
    }
invisible(NULL)
}

rmarkdownTable(head(iris))
```

El código anterior le daría la siguiente figura (en el ejemplo, esta es la salida en pdf, pero como la tabla está en markdwon, también puede tejer en html o word).

ingrese la descripción de la imagen aquí Desde aquí, y leyendo el código de otras personas, puede descubrir cómo manipular el texto para generar la tabla que desea y crear funciones más personalizadas.


1
esto es genial, pero ¿sabes cómo hacer que esto se alinee en el lado izquierdo en lugar de centrarlo?
Patrick

3

use una combinación de knitr :: kable y xtable en su documento de rebajas.

library("knitr","xtable")

para un data.frame simple -

kable(head(mtcars[,1:4]),format="markdown")
kable(head(mtcars[,1:4]),format="pandoc",caption="Title of the table")

format="pandoc" permite más opciones como subtítulos.

Ahora la combinación para el resumen del modelo .

data(tli)
fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data=tli)
kable(xtable(fm1), caption = "Annova table")

para obtener aún más opciones, consulte el stargazerpaquete en lugar de xtable.

ejemplo para uso personal


1

Para escribir / crear tablas de Markdown en R, también puede usar MarkdownReports ' MarkDown_Table_writer_DF_RowColNames() o MarkDown_Table_writer_NamedVector()funciones. Simplemente pasa un marco de datos / matriz con nombres de dimensión, o un vector con nombres, y analiza y escribe la tabla en formato Markdown.


0

Mi función para Gitlab:

to_markdown<-function(df) {
    wrap<-function(x,sep=" ") paste0("|", sep, paste(x, collapse=paste0(sep,"|",sep)), sep, "|", sep=sep)
    paste0(wrap(colnames(df)),
    "\n",
    wrap(rep("------", ncol(df)),sep=""),
    "\n",
    paste(apply(df, 1, wrap), collapse="\n"))
}

cat(to_markdown(head(iris[,1:3])))
| Sepal.Length | Sepal.Width | Petal.Length | 
|------|------|------|
| 5.1 | 3.5 | 1.4 | 
| 4.9 | 3 | 1.4 | 
| 4.7 | 3.2 | 1.3 | 
| 4.6 | 3.1 | 1.5 | 
| 5 | 3.6 | 1.4 | 
| 5.4 | 3.9 | 1.7 | 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.