40 Báo cáo với R Markdown

R Markdown là một công cụ được sử dụng rộng rãi nhằm tạo ra tài liệu tự động, tái lập và chia sẻ được, như các báo cáo. Nó có thể tạo ra kết quả thống kê hoặc tương tác, ở định dạng Word, pdf, html, powerpoint, và các định dạng khác.

Một R Markdown script chứa xen kẽ các code R và văn bản khiến script này thật sự trở thành một tài liệu đầu ra của bạn. Bạn có thể tạo ra một tài liệu đã được định dạng toàn bộ, gồm có văn bản thuần túy (có thể thay đổi dựa trên số liệu của bạn), bảng, biểu đồ, đầu mục/số, thư mục, v.v.

Những tài liệu như vậy có thể được cập nhật thường xuyên (ví dụ: báo cáo giám sát hàng ngày) và/hoặc chạy một tập dữ liệu (ví dụ: báo cáo cho mỗi jurisdiction-quyền xét xử).

Những chương khác trong cuốn sách này mở rộng các chủ đề khác:

Một lưu ý là dự án R4Epis đã tạo ra các mẫu R Markdown script cho những đợt dịch và trường hợp khảo sát phổ biến ở vị trí dự án MSF.

40.1 Chuẩn bị

Nền tảng về R Markdown

Nhằm giải thích một số khái niệm và packages cần thiết:

  • Markdown là một “ngôn ngữ” cho phép bạn soạn tài liệu bằng chữ thuần túy, sau đó có thể chuyển đổi sang html và các định dạng khác. Nó không dành riêng cho R. Các tệp được viết trong Markdown có đuôi ‘.md’.
  • R Markdown: là một biến thể trên markdown chỉ dành riêng cho R - nó cho phép bạn soạn một tài liệu sử dụng markdown để tạo chữ cũng như nhúng code R và hiển thị kết quả đầu ra. Các tệp R Markdown có đuôi ‘.Rmd’.
  • Package rmarkdown: Package được R sử dụng để chuyển tệp .Rmd thành đầu ra mong muốn. Nó tập trung vào việc chuyển cú pháp markdown (chữ), vì vậy chúng ta cũng cần tới…
  • knitr: Package R này sẽ đọc các đoạn code, thực thi chúng, và ‘knit’ (kết hợp) chúng vào lại tài liệu. Đây là cách bảng, biểu đồ được thêm vào văn bản.
  • Pandoc: Cuối cùng, pandoc thật sự chuyển đổi kết quả đầu ra thành word/pdf/powerpoint, v.v. Nó là một phần mềm tách biệt khỏi R nhưng được cài đặt tự động cùng với RStudio.

Tổng kết lại, quá trình được tiến hành trong nền (bạn không cần biết tới tất cả những bước này!), gồm chuyển tệp .Rmd tới knitr để thực thi các đoạn code R và tạo một tệp .md (markdown) mới bao gồm cả code R lẫn kết quả đầu ra đã được chuyển đổi. Các tệp .md này sau đó được pandoc chạy để tạo ra sản phẩm hoàn thiện như là một tài liệu Microsoft Word, tệp HTML, tài liệu powerpoint, pdf, v.v.

(Nguồn: https://rmarkdown.rstudio.com/authoring_quick_tour.html):

Cài đặt

Để tạo một kết quả đầu ra của R Markdown, bạn cần phải cài đặt:

  • Package rmarkdown (knitr cũng sẽ được cài đặt tự động)
  • Pandoc sẽ được cài đặt cùng với RStudio. Nếu bạn không dùng RStudio, bạn có thể tải Pandoc tại đây: http://pandoc.org.
  • Nếu bạn muốn tạo đầu ra là tệp PDF (phức tạp hơn một chút), bạn sẽ cần cài đặt LaTex. Với những người dùng R Markdown chưa cài đặt LaTex trước đó, các bạn có thể cài đặt TinyTeX (https://yihui.name/tinytex/). Bạn có thể sử dụng lệnh sau để cài đặt:
pacman::p_load(tinytex)     # install tinytex package
tinytex::install_tinytex()  # R command to install TinyTeX software 

40.2 Bắt đầu

Cài đặt package rmarkdown

Cài đặt R package rmarkdown. Trong quyển sổ tay này chúng tôi nhấn mạnh việc sử dụng hàm p_load() từ package pacman, giúp cài đặt package nếu cần gọi ra để sử dụng. Bạn cũng có thể cài đặt package với library() từ base R. Xem thêm ở chương R cơ bản để biết thêm thông tin về R packages.

pacman::p_load(rmarkdown)

Bắt đầu một tệp Rmd mới

Trong RStudio, để mở một tệp R markdown mới, bắt đầu với ‘File’, rồi ‘New file’, rồi ‘R markdown…’.

R Studio sẽ đưa ra cho bạn một số lựa chọn kết quả đầu ra. Trong ví dụ bên dưới, chúng tôi chọn “HTML” bởi chúng tôi muốn tạo ra một văn bản html. Tiêu đề và tên các tác giả không quan trọng. Nếu loại tài liệu đầu ra bạn muốn không có, đừng lo - bạn có thể chọn bất kỳ loại nào và thay đổi trong script sau đó.

Như vậy sẽ mở ra một script .Rmd mới.

Điều quan trọng cần phải biết

Thư mục làm việc

Thư mục làm việc của một tệp markdown là ở bất kỳ vị trí nào tệp được lưu. Ví dụ, nếu R project nằm trong ~/Documents/projectX và tệp Rmd được lưu ở thư mục con ~/Documents/projectX/markdownfiles/markdown.Rmd, thì lệnh read.csv(“data.csv”) trong markdown sẽ tìm tệp csv trong thư mục markdownfiles, mà không phải là ở thư mục gốc nơi mà scripts trong projects sẽ thường tự động tìm kiếm.

Để tìm kiếm các tệp này ở chỗ khác, bạn sẽ vừa cần sử dụng cả đường dẫn tệp đầy đủ và sử dụng package here. Package here cài đặt thư mục làm việc tới thư mục gốc của R project và sẽ được giải thích chi tiết trong các chương Dự án RNhập xuất dữ liệu của sổ tay này. Ví dụ, để nhập một tệp tên “data.csv” từ trong thư mục projectX, code sẽ là import(here(“data.csv”)).

Lưu ý rằng không nên sử dụng setwd() trong R Markdown scripts - nó chỉ dùng cho các đoạn code được viết trong đó.

Làm việc với ổ cứng mạng so với trên máy tính của bạn

Vì R Markdown có thể gặp các vấn đề với pandoc khi chạy trên một ổ cứng mạng được chia sẻ, thư mục của bạn nên nằm ở ở cứng vật lý, ví dụ trong dự án thuộc ‘My Documents’. Nếu bạn dùng Git (rất khuyến khích!), nó sẽ thân thuộc hơn. Để biết thêm chi tiết, xem thêm chương R trên ổ cứng mạngCác lỗi thường gặp.

40.3 Các cấu phần của R Markdown

Một tài liệu R Markdown có thể chỉnh sửa trong RStudio giống như một R script tiêu chuẩn. Khi bạn tạo một R Markdown script mới, RStudio vô cùng hữu ích bằng cách đưa ra một mẫu có các phần khác nhau của một tệp R Markdown script.

Dưới đây là khung hiển thị khi bắt đầu một Rmd script mới có kết quả đầu ra là html (như phần trước)

Như bạn có thể thấy, một tệp Rmd gồm có 3 cấu phần: YAML, chữ Markdown, và đoạn code R.

Chúng sẽ tạo ra và trở thành tài liệu đầu ra của bạn. Xem biểu đồ bên dưới:

YAML metadata

‘YAML metadata’ hoặc chỉ ‘YAML’ nằm ở trên cùng trong tài liệu R Markdown. Phần này của script sẽ cho tệp Rmd của bạn biết cần tạo loại kết quả đầu ra nào, định dạng mong muốn, và metadata khác như tiêu đề tài liệu, tác giả, và ngày. Có những công dụng khác không được nhắc ở đây (nhưng được nhắc tới trong ‘Tạo kết quả đầu ra’). Lưu ý rằng có sự thụt đầu dòng, nhưng chỉ chấp nhận spaces chứ không nhận tabs.

Phần này phải được bắt đầu với với một dòng gồm có 3 dấu gạch ngang --- và phải kết thúc với một dòng chỉ có 3 dấu gạch ngang ---. Tham số của YAML ở dạng cặp key:value. Dấu hai chấm trong YAML có vị trí quan trọng - cặp key:value được tách ra bởi dấu hai chấm (không phải dấu bằng!)

YAML nên bắt đầu với metadata cho tài liệu. Thứ tự của những tham số YAML chính (không thụt lề) không quan trọng. Ví dụ:

title: "My document"
author: "Me"
date: "2021-11-01"

Bạn có thể sử dụng code R trong giá trị YAML bằng cách viết nó như code tại dòng (mở đầu bằng r trong dấu back-ticks/nháy đơn ngược) nhưng nằm trong trích dẫn (xem tại ví dụ phía trên với date:).

Trong hình ảnh phía trên, vì chúng ta ấn vào kết quả đầu ra mặc định là tệp html, chúng ta có thể thấy rằng YAML hiện output: html_document. Tuy nhiên, chúng ta cũng có thể thay đổi thành powerpoint_presentation hoặc word_document hoặc cả pdf_document.

Văn bản

Đây là phần diễn giải trong tài liệu của bạn, gồm các tiêu đề và đề mục. Nó được viết bằng ngôn ngữ “markdown”, được sử dụng trên nhiều phần mềm khác nhau.

Dưới đây là những cách cốt lõi để viết văn bản định dạng này. Xem thêm tài liệu mở rộng có sẵn trên R Markdown “cheatsheet” tại Trang web RStudio.

Dòng mới

Duy nhất trong R Markdown, để bắt đầu một dòng mới, nhập *hai dấu cách** vào cuối dòng trước đó và ấn Enter/Return.

Định dạng

Đặt các chữ bình thường bên trong các kí tự sau để thay đổi định dạng của chúng ở đầu ra.

  • Gạch dưới (_chữ_) hoặc dấu hoa thị đơn (*chữ*) để in nghiêng
  • Dấu hoa thị kép (**chữ**) để in đậm
  • Dấu nháy đơn ngược (chữ) để hiển thị chữ như code

Phông chữ hiển thị thực tế có thể được đặt bằng cách sử dụng các mẫu cụ thể (được chỉ định trong YAML metadata; xem các tab ví dụ).

Màu sắc

Không có cơ chế đơn giản nào để thay đổi màu chữ trong R Markdown. Một giải pháp khác, NẾU đầu ra của bạn là tệp HTML, là thêm một dòng HTML vào văn bản markdown. Đoạn mã HTML dưới đây sẽ in ra một dòng văn bản có màu đỏ đậm.

<span style="color: red;">**_DANGER:_** This is a warning.</span>  

DANGER: This is a warning.

Tiêu đề và đầu mục

Dấu thăng trong phần văn bản của một script R Markdown tạo ra đầu mục. Điều này khác với một đoạn code R trong script, trong đó ký hiệu thăng là cơ chế nhận xét/chú thích/hủy kích hoạt, như trong R script bình thường.

Các mức tiêu đề khác nhau được thiết lập với số lượng ký hiệu thăng khác nhau khi bắt đầu một dòng mới. Một ký hiệu thăng là tiêu đề hoặc đầu mục chính. Hai ký hiệu thăng là một đầu mục cấp hai. Các đầu mục cấp ba và cấp bốn có thể được tạo bằng các ký hiệu thăng liên tiếp.

# Đầu mục cấp một / Tiêu đề

## Đầu mục cấp hai

### Đầu mục cấp ba

Dấu đầu dòng và đánh số

Sử dụng dấu hoa thị (*) để tạo danh sách gạch đầu dòng. Kết thúc câu trước, nhập hai dấu cách, Enter/Return hai lần, và bắt đầu tạo gạch đầu dòng. Thêm một dấu cách vào giữa dấu hoa thị và chữ đầu dòng. Sau mỗi đầu dòng nhập hai dấu cách và Enter/Return. Gạch đầu dòng phụ được tạo tương tự nhưng được thụt vào. Các số cũng hoạt động tương tự nhưng thay vì dấu hoa thị, viết 1), 2), v.v. Dưới đây là cách văn bản R Markdown script của bạn trông như thế nào.

Đây là gạch đầu dòng của tôi (có hai dấu cách sau dấu hai chấm này):  

* Gạch đầu dòng 1 (theo sau là 2 dấu cách và Enter/Return)  
* Gạch đầu dòng 2 (theo sau là 2 dấu cách và Enter/Return)  
  * Gạch đầu dòng phụ 1 (theo sau là 2 dấu cách và Enter/Return)  
  * Gạch đầu dòng phụ 2 (theo sau là 2 dấu cách và Enter/Return)  
  

Chữ chú giải

Bạn có thể “chú giải” văn bản R Markdown giống như bạn sử dụng “#” để chú giải một dòng code R trong một đoạn code R. Chỉ cần đánh dấu văn bản và nhấn Ctrl+Shift+c (Cmd+Shift+c cho Mac). Văn bản sẽ được bao quanh bởi các mũi tên và chuyển sang màu xanh lục. Nó sẽ không xuất hiện trong kết quả đầu ra của bạn.

Đoạn Code

Các phần của script dành riêng để chạy code R được gọi là “chunk - đoạn”. Đây là nơi bạn có thể tải các package, nhập dữ liệu và thực hiện quản lý và trực quan hóa dữ liệu thực tế. Có thể có nhiều đoạn code, vì vậy chúng có thể giúp bạn tổ chức code R của mình thành các phần, có thể xen kẽ với văn bản. Cần lưu ý:
Những ‘đoạn’ này sẽ có màu nền hơi khác so với phần diễn giải của tài liệu.

Mỗi đoạn code được mở với một dòng bắt đầu với 3 dấu nháy đơn ngược, và ngoặc nhọn chứa các tham số cho đoạn ({ }). Đoạn code kết thúc với 3 dấu nháy đơn ngược.

Bạn có thể tạo một đoạn code mới bằng cách tự gõ nó ra, hoặc bằng cách sử dụng phím tắt “Ctrl + Alt + i” (hoặc Cmd + Shift + r trong Mac), hoặc bằng cách nhấp vào biểu tượng ‘insert a new code chunk’ màu xanh lục ở đầu trình chỉnh sửa script của bạn.

Một số lưu ý về nội dung bên trong dấu ngoặc nhọn { }:

  • Chúng bắt đầu bằng ‘r’ để chỉ ra rằng tên ngôn ngữ trong đoạn này là R
  • Sau chữ r, bạn có thể tùy ý viết “tên” đoạn - việc này không cần thiết nhưng có thể giúp bạn sắp xếp công việc của mình tốt hơn. Lưu ý rằng nếu bạn đặt tên cho các phần của mình, bạn phải LUÔN sử dụng các tên độc nhất, nếu không R sẽ báo lỗi khi bạn cố gắng kết xuất.
  • Dấu ngoặc nhọn cũng có thể bao gồm các tùy chọn khác, được viết dưới dạng tag = value, chẳng hạn như:
  • eval = FALSE để không chạy code R
  • echo = FALSE để không hiển thị mã nguồn code R của đoạn trong kết quả đầu ra
  • warning = FALSE để không hiển thị cảnh báo được tạo bởi code R
  • message = FALSE để không hiển thị bất kỳ thông báo nào được tạo bởi code R
  • include = TRUE/FALSE có bao gồm đầu ra đoạn code (ví dụ: các đồ thị) trong tài liệu hay không
  • out.width =out.height = - cung cấp theo kiểu out.width = "75%"
  • fig.align = "center" điều chỉnh cách một hình được căn trên trang
  • fig.show='hold' nếu đoạn code của bạn hiển thị nhiều biểu đồ và bạn muốn chúng hiển thị cạnh nhau (cùng với out.width = c("33%", "67%"). Có thể đặt là fig.show='asis' để hiển thị chúng dưới code tạo chúng, 'hide' để ẩn, hoặc 'animate' để nối nhiều cái thành một ảnh động.
  • Tiêu đề đoạn phải được viết trên một dòng
  • Cố gắng tránh dấu chấm, dấu gạch dưới và dấu cách. Sử dụng dấu gạch ngang ( - ) thay thế nếu bạn cần dấu ngăn cách.

Đọc kĩ hơn về các tùy chọn knitr tại đây.

Một số tùy chọn ở trên có thể được định cấu hình với trỏ và nhấp bằng cách sử dụng các nút cài đặt ở trên cùng bên phải của đoạn. Tại đây, bạn có thể chỉ định những phần nào của đoạn mà bạn muốn tài liệu được kết xuất bao gồm cụ thể là code, kết quả đầu ra và cảnh báo. Điều này sẽ xuất hiện dưới dạng tùy chọn được viết trong dấu ngoặc nhọn, ví dụ echo = FALSE nếu bạn muốn ‘Chỉ hiển thị đầu ra’.

Ngoài ra còn có hai mũi tên ở trên cùng bên phải của mỗi đoạn code. Chúng rất hữu ích để chạy code trong một đoạn hoặc tất cả code trong các đoạn trước. Di chuột lên chúng để xem chúng làm gì.

Để các tùy chọn toàn cục được áp dụng cho tất cả các đoạn trong tập lệnh, bạn có thể thiết lập điều này trong đoạn code R đầu tiên của mình trong tập lệnh. Ví dụ, để chỉ các kết quả đầu ra được hiển thị cho mỗi đoạn code chứ không phải bản thân code, bạn có thể đưa lệnh này vào đoạn code R:

knitr::opts_chunk$set(echo = FALSE) 

Code R trong văn bản

Bạn cũng có thể bao gồm code R đơn giản trong dấu nháy đơn ngược. Trong dấu nháy đơn ngược, hãy bắt đầu mã bằng “r” và một dấu cách, để RStudio biết đánh giá code đó là code R. Xem ví dụ bên dưới.

Ví dụ bên dưới hiển thị nhiều cấp tiêu đề, dấu đầu dòng và sử dụng code R cho ngày hiện tại (Sys.Date ()) để chuyển thành ngày in.

Phía trên là một ví dụ đơn giản (hiển thị ngày hiện tại), nhưng sử dụng cùng một cú pháp, bạn có thể hiển thị các giá trị được tạo bởi code R phức tạp hơn (ví dụ: để tính toán giá trị nhỏ nhất, trung bình, giá trị lớn nhất của một cột). Bạn cũng có thể tích hợp các đối tượng hoặc giá trị R đã được tạo trong các đoạn code R trước đó trong script.

Ví dụ, script dưới đây tính toán tỷ lệ các trường hợp dưới 18 tuổi, sử dụng các hàm tidyverse và tạo các đối tượng less18,totalless18prop. Giá trị động này được chèn vào văn bản tiếp theo. Chúng ta thấy nó trông như thế nào khi được knit vào một tài liệu word.

Ảnh

Bạn có thể đưa hình ảnh vào R Markdown của mình theo một trong hai cách:

![]("path/to/image.png")  

Nếu cách trên không được, thử dùng knitr::include_graphics()

knitr::include_graphics("path/to/image.png")

(hãy nhớ rằng, đường dẫn tệp của bạn có thể được viết bằng cách sử dụng package here)

knitr::include_graphics(here::here("path", "to", "image.png"))

Bảng

Tạo bảng bằng dấu gạch ngang ( - ) và dấu thanh ( | ). Số lượng dấu gạch nối trước/giữa các thanh cho phép số lượng khoảng trắng trong ô trước khi văn bản bắt đầu được bao lại.

Cột 1    |Cột  2    |Cột 3
---------|----------|--------
Ô A      |Ô B       |Ô C
Ô D      |Ô E       |Ô F

Code trên tạo ra bảng ở dưới:

Cột 1 Cột 2 Cột 3
Ô A Ô B Ô C
Ô D Ô E Ô F

Các phần được chia thẻ

Đối với đầu ra là tệp HTML, bạn có thể sắp xếp các phần thành các “tab - thẻ”. Chỉ cần thêm .tabset vào trong dấu ngoặc nhọn{}được đặt sau đề mục. Bất kỳ đề mục phụ nào bên dưới tiêu đề đó (cho đến khi tiêu đề khác cùng cấp) sẽ xuất hiện dưới dạng các tab mà người dùng có thể nhấp qua. Đọc thêm tại đây

Bạn có thể thêm một tùy chọn bổ sung .tabset-pills sau .tabset để tạo cho các thẻ có giao diện “được tô màu”. Lưu ý rằng khi xem đầu ra HTML theo thẻ, chức năng tìm kiếm Ctrl+f sẽ chỉ tìm kiếm các tab “đang hoạt động” chứ không phải các thẻ ẩn.

40.4 Cấu trúc tệp

Có nhiều cách để tổ chức R Markdown của bạn và bất kỳ script R nào liên quan. Mỗi cách đều có cả ưu điểm và nhược điểm:

  • R Markdown khép kín - mọi thứ cần thiết cho báo cáo đều được nhập hoặc tạo trong R Markdown
    • Nguồn từ các tệp khác - Bạn có thể chạy các script R bên ngoài bằng lệnh source () và sử dụng đầu ra của chúng trong Rmd
    • Scipt con - một cơ chế thay thế cho source()
  • Sử dụng “runfile” - Chạy các lệnh trong script R trước khi kết xuất tệp R Markdown

Rmd khép kín

Đối với một báo cáo tương đối đơn giản, bạn có thể chọn tổ chức tập lệnh R Markdown của mình sao cho nó “khép kín” và không liên quan đến bất kỳ tập lệnh bên ngoài nào.

Mọi thứ bạn cần để chạy R markdown đều được nhập hoặc tạo trong tệp Rmd, bao gồm tất cả các đoạn code và package. Cách tiếp cận “khép kín” này phù hợp khi bạn không cần xử lý nhiều dữ liệu (ví dụ: nó mang đến một tệp dữ liệu sạch hoặc gần sạch) và việc kết xuất R Markdown sẽ không mất quá nhiều thời gian.

Trong trường hợp này, một cấu trúc hợp lý của script R Markdown có thể là:

  1. Thiết lập các tùy chọn knitr chung
  2. Tải packages
  3. Nhập dữ liệu
  4. Xử lý dữ liệu
  5. Tạo kết quả đầu ra (bảng, đồ thị, etc.)
  6. Lưu kết quả đầu ra nếu cần (.csv, .png, v.v.)

Nguồn từ các tệp khác

Một biến thể của cách tiếp cận “khép kín” là có các đoạn code R Markdown “nguồn” (chạy) chạy các script R khác. Điều này có thể làm cho tập lệnh R Markdown của bạn ít lộn xộn hơn, đơn giản hơn và dễ tổ chức hơn. Nó cũng có thể hữu ích nếu bạn muốn hiển thị số liệu cuối cùng ở đầu báo cáo. Theo cách tiếp cận này, script R Markdown cuối cùng chỉ đơn giản là kết hợp các đầu ra được xử lý trước thành một tài liệu.

Một cách để làm điều này là cung cấp script R (đường dẫn tệp và tên có phần mở rộng) cho lệnh R base source().

source("your-script.R", local = knitr::knit_global())
# or sys.source("your-script.R", envir = knitr::knit_global())

Lưu ý rằng khi sử dụng source () trong R Markdown, các tệp bên ngoài sẽ vẫn được chạy trong quá trình kết xuất tệp Rmd của bạn. Do đó, mỗi tập lệnh được chạy mỗi lần bạn kết xuất báo cáo. Do đó, việc có các lệnh source () này trong R Markdown không tăng tốc thời gian chạy của bạn, cũng như không hỗ trợ nhiều cho việc gỡ lỗi, vì lỗi vẫn được hiển thị khi tạo R Markdown.

Một giải pháp thay thế là sử dụng tùy chọn child = của knitr. GIẢI THÍCH THÊM ĐỂ LÀM

Bạn phải để ý các môi trường R khác nhau. Các đối tượng được tạo trong một môi trường sẽ không nhất thiết phải có sẵn cho môi trường được R Markdown sử dụng.

Runfile

Cách tiếp cận này liên quan đến việc sử dụng R script có chứa (các) lệnh render () để xử lý trước các đối tượng đưa vào R markdown.

Ví dụ, bạn có thể tải các package, tải và làm sạch dữ liệu, và thậm chí tạo các biểu đồ trước khi render(). Các bước này có thể xảy ra trong R script hoặc trong các script khác được lưu nguồn. Miễn là các lệnh này diễn ra trong cùng một phiên RStudio và các đối tượng được lưu vào môi trường, các đối tượng sau đó có thể được gọi trong nội dung Rmd. Sau đó, bản thân R markdown sẽ chỉ được sử dụng cho bước cuối cùng - để tạo ra kết quả với tất cả các đối tượng được xử lý trước. Điều này dễ dàng hơn để gỡ lỗi nếu có sự cố.

Cách tiếp cận này hữu ích vì những lý do sau:

  • Thông báo lỗi mang nhiều thông tin hơn - những thông báo này sẽ được tạo từ R script, không phải R Markdown. Lỗi R Markdown có xu hướng cho bạn biết đoạn nào có vấn đề, nhưng sẽ không cho bạn biết dòng nào.

  • Nếu có thể, bạn có thể chạy các bước xử lý dài trước lệnh render () - chúng sẽ chỉ chạy một lần.

Trong ví dụ bên dưới, chúng ta có một R script riêng biệt, trong đó chúng tôi xử lý trước một đối tượng data vào Môi trường R và sau đó kết xuất “create_output.Rmd” bằng cách sử dụng render().

data <- import("datafile.csv") %>%       # Load data and save to environment
  select(age, hospital, weight)          # Select limited columns

rmarkdown::render(input = "create_output.Rmd")   # Create Rmd file

Cấu trúc thư mục

Quy trình làm việc cũng liên quan đến cấu trúc thư mục tổng thể, chẳng hạn như có thư mục ‘đầu ra’ cho các tài liệu và số liệu đã tạo và thư mục ‘dữ liệu’ hoặc ‘đầu vào’ cho dữ liệu đã được làm sạch. Chúng tôi không đi sâu vào chi tiết ở đây, nhưng hãy xem chương Tổ chức báo cáo định kỳ.

40.5 Tạo tài liệu

Bạn có thể tạo tài liệu theo những cách sau:

  • Thủ công bằng cách nhấn nút “Knit” ở đầu trình chỉnh sửa script RStudio (nhanh chóng và dễ dàng)
  • Chạy lệnh render() (được thực thi bên ngoài R Markdown script)

Cách 1: Nút “Knit”

Khi bạn mở tệp Rmd, hãy nhấn vào biểu tượng/nút ‘Knit’ ở đầu tệp.

R Studio sẽ cho bạn thấy tiến trình trong tab ‘R Markdown’ gần R console của bạn. Tài liệu sẽ tự động mở khi hoàn tất.

Tài liệu sẽ được lưu trong cùng một thư mục với R markdown script của bạn và có cùng tên tệp (ngoại trừ phần mở rộng). Điều này rõ ràng không phải là lý tưởng cho việc kiểm soát phiên bản (nó sẽ bị ghi đè lên mỗi lần bạn knit, trừ khi được di chuyển theo cách thủ công), như sau đó bạn có thể cần phải tự đổi tên tệp (ví dụ: thêm ngày).

Đây là nút tắt của RStudio cho hàm render () từ rmarkdown. Cách tiếp cận này chỉ tương thích với R markdown khép kín, nơi tất cả các thành phần cần thiết tồn tại hoặc có nguồn trong tệp.

Cách 2: Lệnh render()

Một cách khác để tạo đầu ra R Markdown của bạn là chạy hàm render () (từ package rmarkdown). Bạn phải thực hiện lệnh này bên ngoài R Markdown script - vì vậy hoặc trong một tập lệnh R riêng biệt (thường được gọi là “run file”) hoặc dưới dạng lệnh độc lập trong R Console.

rmarkdown::render(input = "my_report.Rmd")

Như với “knit”, cài đặt mặc định sẽ lưu đầu ra Rmd vào cùng thư mục với Rmd script, với cùng tên tệp (ngoài phần mở rộng tệp). Ví dụ: “my_report.Rmd” khi được knit sẽ tạo ra “my_report.docx” nếu bạn đang knit vào một tài liệu word. Tuy nhiên, bằng cách sử dụng render (), bạn có tùy chọn sử dụng các cài đặt khác nhau. render () có thể chấp nhận các đối số bao gồm:

  • output_format = Đây là định dạng đầu ra để chuyển đổi (e.g. "html_document", "pdf_document", "word_document", hoặc "all"). Bạn cũng có thể chỉ định điều này trong YAML bên trong R Markdown script.
  • output_file = Đây là tên của tệp đầu ra (và đường dẫn tệp). Điều này có thể được tạo thông qua các hàm R như here() hoặc str_glue() như minh họa bên dưới.
  • output_dir = Đây là thư mục đầu ra (thư mục) để lưu tệp. Điều này cho phép bạn chọn một thư mục khác với thư mục mà tệp Rmd được lưu vào.
  • output_options = Bạn có thể cung cấp một danh sách các tùy chọn sẽ ghi đè các tùy chọn đó trong script YAML (ví dụ, )
  • output_yaml = Bạn có thể cung cấp đường dẫn đến tệp .yml chứa thông số kỹ thuật YAML
  • params = Xem phần thông số bên dưới
  • Xem danh sách đầy đủ tại đây

Ví dụ, để cải thiện kiểm soát phiên bản, lệnh sau sẽ lưu tệp đầu ra trong thư mục con ‘đầu ra’, với ngày hiện tại trong tên tệp. Để tạo tên tệp, hàm str_glue () từ package stringr được sử dụng để ‘dán’ các chuỗi tĩnh lại với nhau (được viết đơn giản) với code R động (được viết trong dấu ngoặc nhọn). Ví dụ: nếu đó là ngày 10 tháng 4 năm 2021, tên tệp từ bên dưới sẽ là “Report_2021-04-10.docx”. Xem chương Ký tự và chuỗi để biết thêm chi tiết về str_glue ().

rmarkdown::render(
  input = "create_output.Rmd",
  output_file = stringr::str_glue("outputs/Report_{Sys.Date()}.docx")) 

Khi file đang kết xuất, RStudio Console sẽ cho bạn thấy quá trình kết xuất tới 100%, và một thông báo cuối để báo rằng quá trình kết xuất đã hoàn thành.

Cách 3: reportfactory package

R package reportfactory cung cấp một phương pháp thay thế để tổ chức và soạn báo cáo R Markdown phù hợp với các tình huống mà bạn chạy báo cáo thường xuyên (ví dụ hàng ngày, hàng tuần …). Nó giúp giảm bớt việc soạn nhiều tệp R Markdown và tổ chức đầu ra của chúng. Về bản chất, nó cung cấp một “nhà máy” mà từ đó bạn có thể chạy báo cáo R Markdown, nhận các thư mục được đánh dấu ngày tháng và thời gian tự động cho kết quả đầu ra và có cách kiểm soát phiên bản “nhẹ nhàng”.

Đọc thêm về quy trình công việc này trong chương về Tổ chức báo cáo định kỳ.

40.6 Báo cáo được tham số hóa

Bạn có thể sử dụng tham số hóa để tạo báo cáo động, sao cho báo cáo có thể được chạy với cài đặt cụ thể (ví dụ: ngày hoặc địa điểm cụ thể hoặc với các tùy chọn knit nhất định). Dưới đây, chúng tôi tập trung vào những điều cơ bản, nhưng có thêm các tài liệu chi tiết trực tuyến về các báo cáo được tham số hóa.

Sử dụng bộ dữ liệu Ebola có tên linelist làm ví dụ, giả sử chúng ta muốn chạy một báo cáo giám sát tiêu chuẩn cho từng bệnh viện mỗi ngày. Chúng ta chỉ ra cách người ta có thể làm điều này bằng cách sử dụng các tham số.

Quan trọng: các báo cáo động cũng có thể thực hiện được mà không có cấu trúc tham số chính thức (không có params:), bằng cách sử dụng các đối tượng R đơn giản trong R script liền kề. Điều này được giải thích ở cuối phần này.

Cài đặt tham số

Bạn có nhiều cách để chỉ định giá trị tham số cho đầu ra R Markdown của mình.

Cách 1: Đặt tham số trong YAML

Chỉnh sửa YAML để bao gồm tùy chọn params:, với các biểu thức được thụt lề cho mỗi tham số bạn muốn xác định. Trong ví dụ này, chúng tôi tạo các tham số datehospital, với các giá trị mà chúng tôi chỉ định. Các giá trị này có thể thay đổi mỗi khi chạy báo cáo. Nếu bạn sử dụng nút “Knit” để tạo ra đầu ra, các tham số sẽ có các giá trị mặc định này. Tương tự như vậy, nếu bạn sử dụng render (), các tham số sẽ có các giá trị mặc định này trừ khi được chỉ định khác trong lệnh render ().

---
title: Surveillance report
output: html_document
params:
 date: 2021-04-10
 hospital: Central Hospital
---

Ở chế độ nền, các giá trị tham số này được chứa trong danh sách chỉ đọc được gọi là params. Do đó, bạn có thể chèn các giá trị tham số trong code R như cách bạn làm với một đối tượng/giá trị R khác trong môi trường của bạn. Chỉ cần gõ params $ theo sau là tên tham số. Ví dụ: params $ Hospital để đại diện cho tên bệnh viện (“Central Hospital” theo mặc định).

Lưu ý rằng các tham số cũng có thể giữ các giá trị true hoặc false, và vì vậy chúng có thể được đưa vào các tùy chọn knitr của bạn trong một đoạn code R. Ví dụ: bạn có thể đặt {r, eval=params$run} thay vì {r, eval=FALSE}, và bây giờ việc đoạn code chạy hay không phụ thuộc vào giá trị của tham số run:.

Lưu ý rằng đối với các tham số là ngày tháng, chúng sẽ được nhập dưới dạng một chuỗi. Vì vậy, để params$date được diễn giải trong code R, nó có thể sẽ cần được bao bọc bằng as.Date() hoặc một hàm tương tự để chuyển đổi thành lớp Date.

Cách 2: Đặt tham số trong render()

Như đã đề cập ở trên, thay thế cho việc nhấn nút “Knit” để tạo đầu ra là thực thi hàm render() từ một script riêng biệt. Trong trường hợp sau này, bạn có thể chỉ định các tham số được sử dụng trong việc hiển thị đó cho đối số params = của render ().

Lưu ý rằng bất kỳ giá trị tham số nào được cung cấp ở đây sẽ ghi đè các giá trị mặc định của chúng nếu được viết trong YAML. Chúng tôi viết các giá trị trong dấu ngoặc kép vì trong trường hợp này chúng phải được định nghĩa là giá trị ký tự/chuỗi.

Lệnh dưới đây kết xuất tệp “surveillance_report.Rmd”, chỉ định tên và thư mục tệp đầu ra động, đồng thời cung cấp một list() gồm hai tham số và giá trị của chúng cho đối số params =.

rmarkdown::render(
  input = "surveillance_report.Rmd",  
  output_file = stringr::str_glue("outputs/Report_{Sys.Date()}.docx"),
  params = list(date = "2021-04-10", hospital  = "Central Hospital"))

Cách 3: Đặt tham số sử Giao diện Người dùng (GUI)

Để có cảm giác tương tác hơn, bạn cũng có thể sử dụng Giao diện Người dùng (Graphical User Interface - GUI) để chọn thủ công các giá trị cho các tham số. Để thực hiện việc này, chúng ta có thể nhấp vào menu thả xuống bên cạnh nút ‘Knit’ và chọn ‘Knit with parameter’.

Một cửa sổ bật lên sẽ xuất hiện cho phép bạn nhập các giá trị cho các tham số được thiết lập trong YAML của tài liệu.

Bạn có thể đạt được điều tương tự thông qua lệnh render() bằng cách chỉ định params = "ask", như được minh họa bên dưới.

rmarkdown::render(
  input = "surveillance_report.Rmd",  
  output_file = stringr::str_glue("outputs/Report_{Sys.Date()}.docx"),
  params = “ask”)

Tuy nhiên, việc nhập giá trị vào cửa sổ bật lên này có thể xảy ra lỗi và lỗi chính tả. Bạn có thể chọn thêm các hạn chế cho các giá trị có thể được nhập thông qua menu thả xuống. Bạn có thể làm điều này bằng cách thêm vào YAML một số thông số kỹ thuật cho mỗi mục nhập params:.

  • label: là cách tiêu đề cho menu thả xuống cụ thể đó
  • value: là giá trị mặc định (bắt đầu)
  • input: đặt thành select cho menu thả xuống
  • choices: cung cấp các giá trị đủ điều kiện trong menu thả xuống

Dưới đây, các thông số kỹ thuật này được viết cho tham số hospital.

---
title: Surveillance report
output: html_document
params:
 date: 2021-04-10
 hospital: 
  label: “Town:”
  value: Central Hospital
  input: select
  choices: [Central Hospital, Military Hospital, Port Hospital, St. Mark's Maternity Hospital (SMMH)]
---

Khi knit (thông qua nút ‘knit with parameters’ hoặc bằng cách render()), cửa sổ bật lên sẽ có các tùy chọn thả xuống để bạn lựa chọn.

Ví dụ tham số hóa

Đoạn mã sau đây tạo các tham số cho datehospital, được sử dụng trong R Markdown tương ứng là params$dateparams$hospital.

Trong kết quả đầu ra của báo cáo, hãy xem cách dữ liệu được lọc cho bệnh viện cụ thể và tiêu đề biểu đồ đề cập đến bệnh viện và ngày chính xác. Chúng tôi sử dụng tệp “linelist_cleaned.rds” ở đây, nhưng nó sẽ đặc biệt thích hợp nếu bản thân tệp linelist cũng có một dấu ngày tháng bên trong nó để căn chỉnh với ngày được tham số hóa.

Knit sẽ tạo ra kết quả cuối cùng với phông chữ và bố cục mặc định.

Tham số hóa không có params

Nếu bạn đang kết xuất tệp R Markdown với render () từ một script riêng biệt, bạn thực sự có thể tạo ra tác động của tham số hóa mà không cần sử dụng chức năng params:.

Ví dụ, trong R script có chứa lệnh render (), bạn có thể chỉ cần xác định hospitaldate là hai đối tượng R (giá trị) trước lệnh render (). Trong R Markdown, bạn sẽ không cần phải có phần params: trong YAML, và chúng tôi sẽ đề cập đến đối tượng date hơn là params$datehospital hơn là params$hospital.

# This is a R script that is separate from the R Markdown

# define R objects
hospital <- "Central Hospital"
date <- "2021-04-10"

# Render the R markdown
rmarkdown::render(input = "create_output.Rmd") 

Làm theo cách này có nghĩa là bạn không thể “knit với các tham số”, sử dụng GUI hoặc bao gồm các tùy chọn knit trong các tham số. Tuy nhiên, điều này có thể có ích vì nó cho phép code đơn giản hơn.

40.7 Tạo vòng lặp nhiều báo cáo

Chúng ta có thể muốn chạy một báo cáo nhiều lần, thay đổi các thông số đầu vào, để tạo ra một báo cáo cho từng khu vực pháp lý/đơn vị. Điều này có thể được thực hiện bằng cách sử dụng các công cụ cho việc lặp lại, được giải thích chi tiết trong chương về [Lặp, vòng lặp và danh sách]. Các tùy chọn bao gồm package purrr hoặc sử dụng vòng lặp for như được giải thích bên dưới.

Dưới đây, chúng tôi sử dụng vòng lặp for đơn giản để tạo báo cáo giám sát cho tất cả các bệnh viện được chọn. Điều này được thực hiện bằng một lệnh (thay vì thay đổi từng thông số bệnh viện theo cách thủ công). Lệnh kết xuất báo cáo phải tồn tại trong một script riêng biệt bên ngoài báo cáo Rmd. Script này cũng sẽ chứa các đối tượng được xác định để “lặp qua” - ngày hôm nay và một vectơ tên bệnh viện để lặp qua.

hospitals <- c("Central Hospital",
                "Military Hospital", 
                "Port Hospital",
                "St. Mark's Maternity Hospital (SMMH)") 

Sau đó, chúng tôi cung cấp từng giá trị này vào lệnh render() bằng cách sử dụng một vòng lặp, lệnh này chạy lệnh một lần cho mỗi giá trị trong vectơ hospitals. Chữ cái i đại diện cho vị trí chỉ mục (từ 1 đến 4) của bệnh viện hiện đang được sử dụng trong lần lặp đó, như vậy hospital_list[1] sẽ là “Central Hospital”. Thông tin này được cung cấp ở hai nơi trong lệnh render():

  1. Đối với tên tệp, sao cho tên tệp của lần lặp đầu tiên nếu được tạo vào ngày 10 tháng 4 năm 2021 sẽ là “Report_Central Hospital_2021-04-10.docx”, được lưu trong thư mục con ‘output’ của thư mục làm việc.
  2. Với params = sao cho Rmd sử dụng tên bệnh viện trong nội bộ bất cứ khi nào giá trị params$hospital được gọi (ví dụ: chỉ để lọc tập dữ liệu cho bệnh viện cụ thể). Trong ví dụ này, bốn tệp sẽ được tạo - mỗi tệp cho một bệnh viện.
for(i in 1:length(hospitals)){
  rmarkdown::render(
    input = "surveillance_report.Rmd",
    output_file = str_glue("output/Report_{hospitals[i]}_{Sys.Date()}.docx"),
    params = list(hospital  = hospitals[i]))
}       

40.8 Mẫu

Bằng cách sử dụng tài liệu mẫu có chứa bất kỳ định dạng mong muốn nào, bạn có thể điều chỉnh tính thẩm mỹ của đầu ra Rmd sẽ trông như thế nào. Ví dụ, bạn có thể tạo tệp MS Word hoặc Powerpoint chứa các trang/trang trình bày với kích thước, hình đóng dấu, hình nền và phông chữ mong muốn.

Tài liệu Word

Để tạo một mẫu, hãy bắt đầu một tài liệu word mới (hoặc sử dụng đầu ra hiện có với định dạng phù hợp với bạn) và chỉnh sửa phông chữ bằng cách xác định Kiểu. Trong Kiểu, Đầu mục 1, 2 và 3 đề cập đến các cấp đề mục markdown khác nhau (tương ứng #Đề mục 1, ##Đề mục 2### Đề mục 3). Nhấp chuột phải vào kiểu và nhấp vào ‘sửa đổi’ để thay đổi định dạng phông chữ cũng như đoạn văn (ví dụ: bạn có thể giới thiệu các ngắt trang trước các kiểu nhất định có thể giúp giãn cách). Các khía cạnh khác của tài liệu word như lề, kích thước trang, đề mục, v.v., có thể được thay đổi giống như một tài liệu word thông thường mà bạn đang làm việc trực tiếp bên trong.

Tài liệu Powerpoint

Như trên, hãy tạo một slide mới hoặc sử dụng một file powerpoint hiện có với định dạng mong muốn. Để chỉnh sửa thêm, hãy nhấp vào ‘View’ và ‘Slide Master’. Từ đây, bạn có thể thay đổi giao diện trang chiếu ‘master’ bằng cách chỉnh sửa định dạng văn bản trong các hộp văn bản, cũng như kích thước nền/trang cho trang tổng thể.

Thật không may, việc chỉnh sửa tệp powerpoint hơi kém linh hoạt:

  • Đề mục cấp đầu tiên (# Đề mục 1) sẽ tự động trở thành tiêu đề của trang trình bày mới,
  • Chữ ## Đề mục 2 sẽ không xuất hiện dưới dạng phụ đề mà là chữ trong hộp văn bản chính của trang chiếu (trừ khi bạn tìm được cách để làm rộng chế độ xem Master).
  • Các ô và bảng đã xuất sẽ tự động chuyển sang các trang trình bày mới. Bạn sẽ cần kết hợp chúng, chẳng hạn như hàm patchwork để kết hợp các ggplots, để chúng hiển thị trên cùng một trang. Xem bài đăng trên blog về cách sử dụng package patchwork để đặt nhiều hình ảnh trên một trang chiếu.

Xem officer package để biết công cụ làm việc chuyên sâu hơn với các bài thuyết trình powerpoint.

Tích hợp các mẫu vào YAML

Khi một mẫu được chuẩn bị, chi tiết của mẫu này có thể được thêm vào YAML của Rmd bên dưới dòng ‘đầu ra’ và bên dưới nơi loại tài liệu được chỉ định (chính nó sẽ đi đến một dòng riêng). Lưu ý reference_doc có thể được sử dụng cho các mẫu slide powerpoint.

Dễ dàng nhất là lưu mẫu trong cùng một thư mục với nơi chứa tệp Rmd (như trong ví dụ bên dưới) hoặc trong một thư mục con bên trong.

---
title: Surveillance report
output: 
 word_document:
  reference_docx: "template.docx"
params:
 date: 2021-04-10
 hospital: Central Hospital
template:
 
---

Định dạng tệp HTML

Các tệp HTML không sử dụng các mẫu, nhưng có thể có các kiểu được định cấu hình trong YAML. HTML là tài liệu tương tác và đặc biệt linh hoạt. Chúng tôi đề cập đến một số tùy chọn cơ bản ở đây.

  • Mục lục: Chúng ta có thể thêm mục lục với toc: true bên dưới, và cũng chỉ định rằng nó vẫn có thể xem được (“float”) khi bạn cuộn, vớitoc_float: true.

  • Chủ đề: Chúng ta có thể tham khảo một số chủ đề được tạo sẵn, lấy từ thư viện chủ đề của Bootswatch. Trong ví dụ dưới đây, chúng tôi sử dụng cerulean. Các tùy chọn khác bao gồm: journal, flatly, darkly, readable, spacelab, united, cosmo, lumen, paper, sandstone, simplex, và yeti.

  • Đánh dấu: Định cấu hình này sẽ thay đổi giao diện của chữ được đánh dấu (ví dụ: code trong các đoạn được hiển thị). Các kiểu được hỗ trợ bao gồm mặc định, tango, pygments, kate, monochrome, espresso, zenburn, hasdock, breezedark và textmate.

Đây là một ví dụ về cách tích hợp các tùy chọn trên vào YAML.

---
title: "HTML example"
output:
  html_document:
    toc: true
    toc_float: true
    theme: cerulean
    highlight: kate
    
---

Dưới đây là hai ví dụ về kết quả đầu ra HTML, cả hai đều có mục lục nổi, nhưng chủ đề và kiểu đánh dấu khác nhau được chọn:

40.9 Nội dung động

Trong đầu ra HTML, nội dung báo cáo của bạn có thể là động. Dưới đây là một số ví dụ:

Bảng

Trong báo cáo HTML, bạn có thể in khung/ô dữ liệu sao cho nội dung là động, với các bộ lọc và thanh cuộn. Có một số packages cung cấp khả năng này.

Để thực hiện việc này với package DT, như được sử dụng trong cuốn sổ tay này, bạn có thể chèn một đoạn code như sau:

Hàm datatable() sẽ in khung dữ liệu đã cung cấp dưới dạng bảng động cho trình đọc. Bạn có thể đặt rownames = FALSE để đơn giản hóa phần ngoài cùng bên trái của bảng. filter = "top" cung cấp một bộ lọc trên mỗi cột. Trong đối số option() cung cấp danh sách các thông số kỹ thuật khác. Dưới đây, chúng tôi bao gồm hai đối số: pageLength = 5 đặt số hàng xuất hiện là 5 (các hàng còn lại có thể được xem bằng cách phân trang thông qua các mũi tên) vàscrollX = TRUE bật thanh cuộn ở cuối bảng (đối với cột mở rộng quá xa sang bên phải).

Nếu tập dữ liệu của bạn rất lớn, hãy xem xét chỉ hiển thị X hàng trên cùng bằng cách gói khung dữ liệu trong head().

Tiện ích HTML

Tiện ích HTML cho R là một lớp packages R đặc biệt cho phép tăng tính tương tác bằng cách sử dụng các thư viện JavaScript. Bạn có thể nhúng chúng vào các đầu ra HTML R Markdown.

Một số ví dụ phổ biến về các tiện ích này bao gồm:

  • Plotly (được sử dụng trong chương sổ tay này và trong chương Biểu đồ tương tác)
  • visNetwork (được sử dụng trong chương Chuỗi lây nhiễm của sổ tay này)
  • Leaflet (được sử dụng trong chương GIS Cơ bản của sổ tay này)
  • dygraphs ( hữu ích để hiển thị dữ liệu chuỗi thời gian tương tác)
  • DT (datatable()) (được sử dụng để hiển thị các bảng động với bộ lọc, sắp xếp, v.v.)

Hàm ggplotly() từ plotly đặc biệt dễ sử dụng. Xem chương Biểu đồ tương tác.

40.10 Tài nguyên

Tìm thêm thông tin tại:

Một giải thích tốt về so sánh giữa markdown, knitr và Rmarkdown ở đây: https://stackoverflow.com/questions/40563479/relationship-between-r-markdown-knitr-pandoc-and-bookdown