Creazione programmatica di tabelle Markdown in R con KnitR


103

Sto appena iniziando a conoscere KnitR e l'uso di Markdown nella generazione di documenti e report R. Questo sembra essere perfetto per la maggior parte dei rapporti quotidiani che ho a che fare con il mio lavoro. Tuttavia, una cosa che non vedo è un modo semplice per stampare frame di dati e tabelle usando la formattazione Markdown (un po 'come xtable, ma con Markdown invece di LaTeX o HTML). So che posso semplicemente incorporare l'output HTML da xtable, ma mi chiedevo se esistessero soluzioni basate su Markdown?


3
Considerando xtable e html .. Stampa il codice html con print(xtable(data), type = "html").
— user974514

7
@TARehman La tua domanda mi ha ricordato che non esisteva ancora una soluzione che producesse tabelle direttamente compatibili knitr, quindi ho inviato una richiesta pull a panderper aggiungere lo stile della tabella. Nelle versioni future di pander, dovresti essere in grado di farepandoc.table(iris, style="rmarkdown")
— Marius

1
@Mario Sapete per caso perché Pandoc non fa parte di CRAN? O quando potrebbe diventarne parte? Solo curioso.
— TARehman

2
@TARehman Non sono del tutto sicuro se intendevi pander o pandoc. panderdovrebbe essere su CRAN. pandoc è un programma scritto in Haskell che converte in e da un'ampia varietà di formati diversi, non è in alcun modo specifico per R.
— Marius

1
Scusa, volevo dire pander, che non era su CRAN l'ultima volta che avevo sentito - no pandoc. Colpa mia. :)
— TARehman

Risposte:


122

Ora knitr(dalla versione 1.3) il pacchetto include la kablefunzione per la creazione di tabelle:

> 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|

AGGIORNATO : se si ottiene un markdown grezzo in un documento, provare l' results = "asis"opzione di blocco di configurazione .


24
quando esegui all'interno di knitr, puoi omettere l' formatargomento, poiché knitr è a conoscenza del formato di output e lo imposterà automaticamente
— Yihui Xie

3
@Yihui Sei incredibile
— isomorfismi

2
Ho provato questo, ma `` {r} kable (...) mostra solo il ribasso grezzo
— Alex Brown

6
Prova a impostare l'opzione blocco locale su results = asis.
— Artem Klevtsov

5
FYI knitr ora richiede il comando nel formatoresults = 'asis'
— Stedy

32

Due pacchetti che faranno questo sono pander

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

O ascii

pander è un approccio leggermente diverso alla costruzione dei report, (ma può essere utile per questa funzionalità).

asciiti permetterà di printcon type = 'pandoc(o vari altri gusti di ribasso)

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              
--- ------------------ ----------------- ------------------

Nota che in entrambi questi casi, è diretto verso l'utilizzo pandocper convertire da markdown al tipo di documento desiderato, tuttavia l'utilizzo style='rmarkdown'creerà tabelle compatibili con questo markdownpacchetto e la conversione incorporata in rstudio.


3
Solo una nota a riguardo pander: può produrre i rmarkdowntavoli in stile anche accanto ad altri, ad esempio:pander(head(iris[,1:3]), style = 'rmarkdown')
— daroczig

@daroczig - Grazie e annotato nella risposta ora,
— mnel

26

Volevo solo aggiornare questo con quello che ho deciso di fare. Sto usando il hwriterpacchetto in questo momento per stampare le tabelle e usando le funzionalità row.*e col.*per inserire classi CSS su elementi diversi. Quindi, ho scritto CSS personalizzato per rendere la mia visualizzazione come volevo. Quindi, ecco un esempio nel caso in cui qualcun altro abbia a che fare con qualcosa di simile.

Innanzitutto, crea un file che eseguirà knittinge cambierà il Markdown in HTML:

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

library(knitr)
library(markdown)

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

Quindi, crea il file Markdown effettivo:

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"))))
```

Infine, crea un file CSS personalizzato.

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;
}

L'esecuzione ./file_knit.rmi dà file.html, che assomiglia a questo:

Output di esempio

Quindi, si spera che questo possa essere utile ad altri che desiderano un po 'più di formattazione nell'output di Markdown!


1
Sì, no. Funzionerà con Markdown -> HTML ma non con Markdown -> PDF, Markdown -> DOCX ... La domanda riguarda l'utilizzo di Markdown in generale non solo allo scopo di creare file HTML con esso - potrebbe essere stato il tuo intenzione, ma non è scritto laggiù.
— petermeissner

Hai notato che sto rispondendo alla mia stessa domanda? Posso modificare la domanda o taggarla in modo diverso se pensi che possa aiutare?
— TARehman

Per inciso, al momento di questa risposta, knitr supportava solo HTML. Ecco perché la domanda non dice esplicitamente nulla sull'HTML.
— TARehman

jip, cambiare la domanda aiuterebbe ... ma perché renderla più specifica quando è più utile per tutti quando è più ampia e più generale? Per quanto riguarda la tua risposta alla tua domanda, beh, gli altri forniscono tabelle in formato Markdown, tu fornisci tabelle in formato HTML - non è sbagliato ma trovo le altre risposte semplicemente giuste, eleganti e più utili. non tutti devono apprezzare la tua risposta, non è sufficiente che piaccia la tua risposta?
— petermeissner

7
Tu stesso hai detto che la mia risposta non è sbagliata, ma che gli altri sono migliori. La corretta applicazione del sistema di voto consiste nel votare a favore delle risposte migliori, non nel votare in negativo il mio. Vedi anche qui: stackoverflow.com/help/privileges/vote-down "Usa i tuoi voti negativi ogni volta che incontri un messaggio incredibilmente sciatto, senza sforzi o una risposta che è chiaramente e forse pericolosamente errata."
— TARehman

18

Ci sono funzioni nel panderpacchetto:

> 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
Grazie per la promozione pander:) Tieni presente che potresti anche utilizzare il metodo generico S3 per salvare alcuni caratteri da digitare, come:pander(head(iris)[, 1:3])
— daroczig

12

Non è molto difficile creare una funzione personalizzata. Ecco una dimostrazione di concetto molto semplice per generare una tabella rmarkdown di 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)
    }

Nel documento .Rmd dovresti quindi utilizzare la funzione 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))
```

Il codice sopra ti darebbe la seguente figura (nell'esempio questo è l'output pdf, ma poiché la tabella è in markdwon, potresti lavorare anche in html o word).

inserisci qui la descrizione dell'immagine Da qui - e leggendo il codice di altre persone - puoi capire come manipolare il testo per generare la tabella che desideri e creare funzioni più personalizzate.


1
questo è fantastico, ma sai come farlo allineare sul lato sinistro invece che centrato?
— Patrick

3

usa una combinazione di knitr :: kable e xtable nel tuo documento markdown.

library("knitr","xtable")

per un semplice data.frame -

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

format="pandoc" consente più opzioni come didascalia.

Ora la combinazione per il riepilogo del modello .

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

per ancora più opzioni guarda stargazerpackage invece di xtable.

esempio per uso personale


1

Per scrivere / creare tabelle Markdown in R, puoi anche usare MarkdownReports ' MarkDown_Table_writer_DF_RowColNames() o MarkDown_Table_writer_NamedVector()funzioni. Basta passare un data frame / matrice con nomi di dimensioni o un vettore con nomi e analizza e scrive la tabella in formato Markdown.


0

La mia funzione per 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 | 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.