Lập trình tạo bảng Markdown trong R với KnitR


103

Tôi mới bắt đầu tìm hiểu về KnitR và việc sử dụng Markdown trong việc tạo tài liệu và báo cáo R. Điều này có vẻ là hoàn hảo cho rất nhiều ngày báo cáo rằng tôi phải làm với công việc của mình. Tuy nhiên, có một điều mà tôi không thấy là một cách dễ dàng để in các khung và bảng dữ liệu bằng cách sử dụng định dạng Markdown (tương tự như vậy xtable, nhưng với Markdown thay vì LaTeX hoặc HTML). Tôi biết rằng tôi chỉ có thể nhúng đầu ra HTML từ xtable, nhưng tôi tự hỏi liệu có giải pháp nào dựa trên Markdown không?


3
Xét xtable và html .. In mã html với print(xtable(data), type = "html").
user974514

7
@TARehman Câu hỏi của bạn nhắc nhở tôi rằng vẫn chưa có giải pháp nào tạo ra các bảng tương thích trực tiếp với nó knitr, vì vậy tôi đã gửi một yêu cầu kéo panderđể thêm kiểu bảng. Trong các phiên bản tương lai của pander, bạn sẽ có thể làm đượcpandoc.table(iris, style="rmarkdown")
Marius

1
@Marius Bạn có biết tại sao pandoc không phải là một phần của CRAN không? Hoặc khi nó có thể trở thành một phần của nó? Chỉ tò mò.
TARehman

2
@TARehman Tôi không chắc liệu bạn muốn nói là kẻ lang thang hay kẻ tiểu nhân. pandernên được lên trên CRAN. pandoc là một chương trình được viết bằng Haskell có thể chuyển đổi sang và từ nhiều định dạng khác nhau, nó không dành riêng cho R theo bất kỳ cách nào.
Marius

1
Xin lỗi, ý tôi là pander, điều này không có trên CRAN lần trước tôi đã nghe - không phải pandoc. Lỗi của tôi. :)
TARehman

Câu trả lời:


122

knitrGói bây giờ (kể từ phiên bản 1.3) bao gồm kablechức năng cho một bảng tạo:

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

CẬP NHẬT : nếu bạn bị đánh dấu thô trong tài liệu, hãy thử thiết lập results = "asis"tùy chọn phân đoạn.


24
khi chạy bên knitr, bạn có thể bỏ qua các formatđối số, kể từ knitr là nhận thức được định dạng đầu ra và sẽ tự động thiết lập nó
Yihui Xie

3
@Yihui Bạn thật tuyệt vời
isomorphismes

2
Tôi đã thử điều này, nhưng `` {r} kable (...) chỉ hiển thị điểm đánh dấu thô
Alex Brown

6
Cố gắng đặt tùy chọn đoạn cục bộ thành results = asis.
Artem Klevtsov

5
FYI đantr hiện yêu cầu lệnh ở định dạngresults = 'asis'
Stedy

32

Hai gói sẽ làm điều này là pander

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

Hoặc ascii

pander là một cách tiếp cận hơi khác để xây dựng báo cáo, (nhưng có thể hữu ích cho tính năng này).

asciisẽ cho phép bạn printvới type = 'pandoc(hoặc nhiều hương vị đánh dấu khác)

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

Lưu ý rằng trong cả hai trường hợp này, nó được hướng tới việc sử dụng pandocđể chuyển đổi từ đánh dấu sang loại tài liệu mong muốn của bạn, tuy nhiên việc sử dụng style='rmarkdown'sẽ tạo ra các bảng tương thích với markdowngói này và chuyển đổi sẵn có trong rstudio.


3
Chỉ cần một lưu ý về pander: nó có thể tạo ra các rmarkdownbảng kiểu cũng bên cạnh những người khác, ví dụ như:pander(head(iris[,1:3]), style = 'rmarkdown')
daroczig

@daroczig - Cảm ơn và đã lưu ý trong câu trả lời ngay bây giờ,
mnel

26

Tôi chỉ muốn cập nhật điều này với những gì tôi đã giải quyết. Tôi đang sử dụng hwritergói ngay bây giờ để in ra các bảng và sử dụng các tính năng row.*col.*để đặt các lớp CSS vào các phần tử khác nhau. Sau đó, tôi viết CSS tùy chỉnh để hiển thị như tôi muốn. Vì vậy, đây là một ví dụ trong trường hợp bất kỳ ai khác đang xử lý một cái gì đó tương tự.

Trước tiên, hãy tạo một tệp sẽ thực hiện knittingvà thay đổi Markdown thành HTML:

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

library(knitr)
library(markdown)

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

Tiếp theo, tạo tệp Markdown thực tế:

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

Cuối cùng, chỉ cần tạo một tệp CSS tùy chỉnh.

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

Việc thực thi ./file_knit.rcung cấp cho tôi tệp.html, trông giống như sau:

Đầu ra mẫu

Vì vậy, hy vọng điều này có thể hữu ích cho những người muốn định dạng nhiều hơn một chút trong đầu ra Markdown!


1
Vâng, không. Sẽ hoạt động với Markdown -> HTML nhưng không hoạt động với Markdown -> PDF, Markdown -> DOCX ... Câu hỏi là về việc sử dụng Markdown nói chung không chỉ cho mục đích tạo tệp HTML với nó - có thể là của bạn. ý định, nhưng không được viết ra ở đó.
petermeissner

Bạn có nhận thấy tôi đang trả lời câu hỏi của chính mình không? Tôi có thể chỉnh sửa câu hỏi hoặc gắn thẻ nó theo cách khác nếu bạn nghĩ nó sẽ hữu ích?
TARehman

Thật ngẫu nhiên, tại thời điểm trả lời câu trả lời này, thì nội dung này chỉ hỗ trợ HTML. Đó là lý do tại sao câu hỏi không nói rõ ràng bất cứ điều gì về HTML.
TARehman

jip, thay đổi câu hỏi sẽ hữu ích ... nhưng tại sao phải làm cho nó cụ thể hơn khi nó được sử dụng nhiều hơn cho tất cả mọi người khi nó rộng hơn và tổng quát hơn? Liên quan đến việc bạn trả lời câu hỏi của chính mình, những người khác cung cấp bảng ở định dạng Markdown, bạn cung cấp bảng ở định dạng HTML - điều đó không sai nhưng tôi thấy các câu trả lời khác đơn giản là đi vào vấn đề, thanh lịch và hữu ích hơn. không phải tất cả mọi người đều phải thích câu trả lời của bạn, nó không đủ thích câu trả lời của bạn?
petermeissner

7
Chính bạn đã nói rằng câu trả lời của tôi là không sai, nhưng những người khác tốt hơn. Ứng dụng chính xác của hệ thống bỏ phiếu là ủng hộ những câu trả lời tốt hơn, không phải để phản đối của tôi. Xem thêm tại đây: stackoverflow.com/help/privileges/vote-down "Sử dụng phiếu phản đối của bạn bất cứ khi nào bạn gặp một bài đăng cẩu thả, không tốn nhiều công sức hoặc một câu trả lời rõ ràng và có thể không chính xác một cách nguy hiểm."
TARehman

18

Có các chức năng trong pandergói:

> 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
Cảm ơn để thúc đẩy pander:) lưu ý hãy là bạn cũng có thể sử dụng phương pháp S3 chung để tiết kiệm một vài ký tự gõ, như:pander(head(iris)[, 1:3])
daroczig

12

Không khó lắm để tạo chức năng tùy chỉnh của riêng bạn. Đây là một bằng chứng rất đơn giản về khái niệm để tạo một bảng rmarkdown của một 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)
    }

Trong tài liệu .Rmd sau đó, bạn sẽ sử dụng hàm với 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))
```

Đoạn mã trên sẽ cung cấp cho bạn hình sau (trong ví dụ đây là đầu ra pdf, nhưng vì bảng ở dạng markdwon, bạn có thể đan thành html hoặc word).

nhập mô tả hình ảnh ở đây Từ đây - và đọc mã của người khác - bạn có thể tìm ra cách thao tác văn bản để tạo bảng bạn muốn và tạo thêm các hàm được cá nhân hóa.


1
điều này thật tuyệt, nhưng bạn có biết cách căn chỉnh này ở bên trái thay vì căn giữa không?
Patrick

3

sử dụng sự kết hợp của đan xen :: kable và xtable trong tài liệu đánh dấu của bạn.

library("knitr","xtable")

cho một data.frame đơn giản -

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

format="pandoc" cho phép nhiều tùy chọn hơn như chú thích.

Bây giờ là sự kết hợp để tóm tắt mô hình .

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

để có nhiều tùy chọn hơn, hãy xem stargazergói thay vì xtable.

ví dụ cho sử dụng cá nhân


1

Để viết / tạo bảng Markdown trong R, bạn cũng có thể sử dụng MarkdownReports ' MarkDown_Table_writer_DF_RowColNames() hoặc các MarkDown_Table_writer_NamedVector()hàm. Bạn chỉ cần chuyển một khung dữ liệu / ma trận với các tên thứ nguyên hoặc một vectơ có tên, và nó phân tích cú pháp & ghi ra bảng ở định dạng Markdown.


0

Chức năng của tôi cho 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 | 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.