การสร้างตาราง Markdown แบบเป็นโปรแกรมใน R ด้วย KnitR


103

ฉันเพิ่งเริ่มเรียนรู้เกี่ยวกับ KnitR และการใช้ Markdown ในการสร้างเอกสาร R และรายงาน สิ่งนี้ดูจะเหมาะสำหรับการรายงานประจำวันที่ฉันต้องทำกับงานของฉัน อย่างไรก็ตามสิ่งหนึ่งที่ฉันไม่เห็นคือวิธีง่ายๆในการพิมพ์เฟรมข้อมูลและตารางโดยใช้การจัดรูปแบบ Markdown (คล้ายxtableกัน แต่ใช้ Markdown แทน LaTeX หรือ HTML) ฉันรู้ว่าฉันสามารถฝังเอาต์พุต HTML จาก xtable ได้ แต่ฉันสงสัยว่ามีโซลูชันที่ใช้ Markdown หรือไม่?


3
พิจารณา xtable และ html .. พิมพ์รหัส html ด้วยprint(xtable(data), type = "html").
user974514

7
@TARehman คำถามของคุณเตือนฉันว่ายังไม่มีวิธีแก้ปัญหาที่สร้างตารางที่เข้ากันได้โดยตรงknitrดังนั้นฉันจึงส่งคำขอดึงpanderเพื่อเพิ่มรูปแบบตาราง ในรุ่นต่อ ๆpanderไปคุณควรจะทำได้pandoc.table(iris, style="rmarkdown")
Marius

1
@Marius คุณรู้หรือไม่ว่าทำไม pandoc ถึงไม่เป็นส่วนหนึ่งของ CRAN? หรือเมื่อใดที่อาจกลายเป็นส่วนหนึ่งของมัน? แค่สงสัย.
TARehman

2
@TARehman ฉันไม่ค่อยแน่ใจว่าคุณหมายถึงแพนเดอร์หรือแพนดอค panderควรขึ้นอยู่กับ CRAN pandoc เป็นโปรแกรมที่เขียนขึ้นใน Haskell ซึ่งจะแปลงและแปลงไฟล์จากรูปแบบที่แตกต่างกันมากมายโดยไม่ได้เจาะจงเฉพาะ R แต่อย่างใด
Marius

1
ขออภัยที่ฉันหมายpanderซึ่งไม่ได้อยู่ในช่วงเวลาที่ผ่านมา CRAN ผมเคยได้ยิน - pandocไม่ได้ ความผิดของฉัน. :)
TARehman

คำตอบ:


122

knitrแพ็คเกจตอนนี้(ตั้งแต่เวอร์ชัน 1.3) มีkableฟังก์ชันสำหรับตารางการสร้าง:

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

อัปเดต : หากคุณได้รับข้อมูลดิบในเอกสารให้ลองตั้งค่าresults = "asis"ตัวเลือกก้อน


24
เมื่อทำงานภายในเครื่องถักคุณสามารถละทิ้งformatอาร์กิวเมนต์ได้เนื่องจาก knitr ตระหนักถึงรูปแบบผลลัพธ์และจะตั้งค่าโดยอัตโนมัติ
Yihui Xie

3
@Yihui คุณยอดเยี่ยมมาก
isomorphismes

2
ฉันลองสิ่งนี้ แต่ `` {r} kable (... ) เพิ่งแสดงการลดราคาแบบดิบ
Alex Brown

6
results = asisพยายามที่จะตั้งค่าตัวเลือกก้อนท้องถิ่นเพื่อ
Artem Klevtsov

5
ตอนนี้ FYI knitr ต้องการคำสั่งในรูปแบบresults = 'asis'
Stedy

32

สองแพ็คเกจที่จะทำคือแพนเดอร์

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

หรือascii

pander เป็นวิธีการรายงานการก่อสร้างที่แตกต่างกันเล็กน้อย (แต่อาจมีประโยชน์สำหรับคุณลักษณะนี้)

asciiจะช่วยให้คุณprintมีtype = 'pandoc(หรือรสชาติต่างๆ markdown อื่น ๆ )

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

โปรดสังเกตว่าในทั้งสองกรณีเหล่านี้ก็จะนำไปใช้pandocการแปลงจาก markdown ประเภทเอกสารที่คุณต้องการ แต่ใช้style='rmarkdown'จะสร้างตารางที่เข้ากันได้กับเรื่องนี้markdownแพคเกจและการแปลง inbuilt rstudioใน


3
หมายเหตุเกี่ยวกับpander: สามารถสร้างrmarkdownตารางสไตล์อื่น ๆ ได้เช่น:pander(head(iris[,1:3]), style = 'rmarkdown')
daroczig

@daroczig - ขอบคุณและระบุไว้ในคำตอบตอนนี้
mnel

26

แค่อยากจะอัปเดตสิ่งนี้กับสิ่งที่ฉันตัดสินใจทำ ตอนนี้ฉันใช้hwriterแพคเกจเพื่อพิมพ์ตารางและใช้คุณสมบัติrow.*และcol.*เพื่อใส่คลาส CSS ให้กับองค์ประกอบต่างๆ จากนั้นฉันเขียน CSS ที่กำหนดเองเพื่อให้แสดงผลตามที่ฉันต้องการ ดังนั้นนี่คือตัวอย่างในกรณีที่ใครก็ตามกำลังเผชิญกับสิ่งที่คล้ายกัน

ขั้นแรกสร้างไฟล์ที่จะทำknittingและเปลี่ยน Markdown เป็น HTML:

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

library(knitr)
library(markdown)

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

จากนั้นสร้างไฟล์ Markdown จริง:

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

สุดท้ายเพียงสร้างไฟล์ CSS ที่กำหนดเอง

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

การดำเนินการ./file_knit.rทำให้ฉันได้ file.html ซึ่งมีลักษณะดังนี้:

ตัวอย่างผลลัพธ์

ดังนั้นหวังว่านี่อาจเป็นประโยชน์สำหรับผู้อื่นที่ต้องการการจัดรูปแบบเพิ่มเติมเล็กน้อยในเอาต์พุต Markdown!


1
ใช่ไม่ จะทำงานร่วมกับ Markdown -> HTML แต่ไม่ใช่กับ Markdown -> PDF, Markdown -> DOCX ... คำถามเกี่ยวกับการใช้ Markdown โดยทั่วไปไม่เพียง แต่เพื่อวัตถุประสงค์ในการสร้างไฟล์ HTML ด้วย - อาจเป็นของคุณ ความตั้งใจ แต่ไม่ได้เขียนไว้ที่นั่น
petermeissner

สังเกตไหมว่าฉันกำลังตอบคำถามของตัวเอง ฉันสามารถแก้ไขคำถามหรือแท็กให้แตกต่างออกไปได้ถ้าคุณคิดว่าจะช่วยได้?
TARehman

อนึ่งในขณะที่ตอบคำถามนี้ Knitr สนับสนุนเฉพาะ HTML นั่นเป็นเหตุผลว่าทำไมคำถามจึงไม่พูดอะไรเกี่ยวกับ HTML อย่างชัดเจน
TARehman

jip การเปลี่ยนคำถามจะช่วยได้ ... แต่ทำไมต้องเจาะจงมากขึ้นในเมื่อมันมีประโยชน์มากขึ้นสำหรับทุกคนในเมื่อมันกว้างขึ้นและกว้างขึ้น? สำหรับคุณที่ตอบคำถามของคุณเองคนอื่น ๆ ก็ให้ตารางในรูปแบบ Markdown ที่คุณให้ตารางในรูปแบบ HTML ไม่ใช่เรื่องผิด แต่ฉันพบว่าคำตอบอื่น ๆ นั้นตรงประเด็นหรูหราและเป็นประโยชน์มากกว่า ไม่ใช่ทุกคนที่จะชอบคำตอบของคุณมันไม่เพียงพอที่จะตอบสนองคำตอบของคุณหรือไม่?
petermeissner

7
คุณเองเคยบอกว่าคำตอบของฉันไม่ผิด แต่คนอื่นดีกว่า การใช้ระบบการลงคะแนนที่ถูกต้องคือการโหวตคำตอบที่ดีกว่าไม่ใช่การโหวตให้ฉัน ดูเพิ่มเติมที่นี่: stackoverflow.com/help/privileges/vote-down "ใช้ downvote ของคุณเมื่อใดก็ตามที่คุณพบโพสต์ที่เลอะเทอะอย่างมากโดยไม่ต้องใช้ความพยายามหรือคำตอบที่ชัดเจนและอาจไม่ถูกต้องเป็นอันตราย"
TARehman

18

มีฟังก์ชั่นในpanderแพ็คเกจ:

> 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
ขอบคุณสำหรับการส่งเสริมpander:) โปรดทราบว่าคุณอาจใช้วิธี S3 ทั่วไปเพื่อบันทึกอักขระบางตัวที่จะพิมพ์เช่น:pander(head(iris)[, 1:3])
daroczig

12

ไม่ยากที่จะสร้างฟังก์ชันที่กำหนดเองของคุณเอง นี่คือข้อพิสูจน์แนวคิดง่ายๆในการสร้างตาราง rmarkdown ของ 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)
    }

ในเอกสาร. rmd คุณจะใช้ฟังก์ชันกับ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))
```

โค้ดด้านบนจะให้รูปต่อไปนี้ (ในตัวอย่างนี่คือเอาต์พุต pdf แต่เนื่องจากตารางอยู่ใน markdwon คุณสามารถถักเป็น html หรือ word ได้ด้วย)

ป้อนคำอธิบายภาพที่นี่ จากที่นี่ - และอ่านโค้ดของคนอื่น - คุณสามารถค้นหาวิธีจัดการข้อความเพื่อสร้างตารางที่คุณต้องการและสร้างฟังก์ชันที่เป็นส่วนตัวมากขึ้น


1
มันเยี่ยมมาก แต่คุณรู้วิธีจัดแนวนี้ทางด้านซ้ายแทนที่จะจัดกึ่งกลาง?
Patrick

3

ใช้การรวมกันของ knitr :: kable และ xtable ในเอกสาร markdown ของคุณ

library("knitr","xtable")

สำหรับ data.frame อย่างง่าย -

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

format="pandoc" ช่วยให้มีตัวเลือกเพิ่มเติมเช่นคำอธิบายภาพ

ตอนนี้รวมกันเพื่อสรุปรูปแบบ

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

สำหรับตัวเลือกมากขึ้นดูที่แพคเกจแทนstargazerxtable

ตัวอย่างสำหรับการใช้งานส่วนตัว


1

ในการเขียน / สร้างตาราง Markdown ใน R คุณยังสามารถใช้MarkdownReports MarkDown_Table_writer_DF_RowColNames()หรือMarkDown_Table_writer_NamedVector()ฟังก์ชัน คุณเพียงแค่ส่งเฟรมข้อมูล / เมทริกซ์ที่มีชื่อมิติข้อมูลหรือเวกเตอร์ที่มีชื่อจากนั้นจะแยกวิเคราะห์และเขียนตารางในรูปแบบ Markdown


0

ฟังก์ชั่นของฉันสำหรับ 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 | 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.