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.