Reports with R Markdown

Reviewed & published by Brayan K

R Markdown is a document format that mixes Markdown prose with runnable R code chunks, so that a single "knit" produces a reproducible report — HTML, PDF, or Word — where every number, table, and plot is generated straight from your data.

Part of the free R course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

By the end of this lesson you'll write the YAML header, add code chunks and inline R, control output with chunk options, and knit a polished, reproducible report.

What You'll Learn in This Lesson

1️⃣ The YAML Header and Markdown Body

Every .Rmd file opens with a YAML header between two --- lines that sets the title, author, and most importantly the output format. Below it you write ordinary Markdown — headings with #, bold with **...**, and bullet lists.

---
title: "Monthly Sales Report"
author: "Your Name"
date: "2026-06-18"
output: html_document
---

# Overview

This is a paragraph of **Markdown**. You write prose normally and
drop in R wherever you need numbers, tables, or plots.

## A bullet list

- Markdown handles formatting
- R chunks handle computation
- One "Knit" turns it all into a polished document

2️⃣ Code Chunks and Inline R

A code chunk opens with a fenced header — three backticks then {r} — and closes with three backticks. Knitr runs the code and inserts the result. For a single value inside a sentence, use inline R: a backtick, the letter r, your expression, then a closing backtick.

${fence}{r}
# This is a CODE CHUNK. The header ${fence}{r} opens it; ${fence} closes it.
# When you knit, R RUNS this code and drops the result into the report.

sales <- c(120, 135, 150, 165)
mean(sales)
${fence}

You can label a chunk and set OPTIONS in its header:

${fence}{r summary-stats, echo=FALSE}
# echo=FALSE  -> hide the CODE, show only the OUTPUT
summary(sales)
${fence}

${fence}{r the-plot, fig.width=6, fig.height=4}
# fig.width / fig.height control the plot size in the output
plot(sales, type = "b", main = "Monthly Sales")
${fence}
You can weave R results into a SENTENCE with inline code.
Write a backtick, the letter r, an expression, then a closing backtick:

The average sale was `r mean(sales)` units, across
`r length(sales)` months.

When knitted, that line becomes:

The average sale was 142.5 units, across 4 months.

Inline R is perfect for figures that must always match the data —
no more copy-pasting numbers that go stale when the data updates.

3️⃣ Chunk Options and Knitting

Each chunk header can carry options that shape what appears: echo=FALSE hides the code, eval=FALSE skips running it, and fig.width/fig.height size plots. Set document-wide defaults in a setup chunk, then knit to HTML, PDF, or Word.

# Common chunk options (set per-chunk in the ${fence}{r ...} header):
#
#   echo    = TRUE/FALSE   show or hide the source code
#   eval    = TRUE/FALSE   run the chunk or skip it
#   include = FALSE        run it, but show NEITHER code nor output
#   warning = FALSE        suppress warnings in the report
#   message = FALSE        suppress package-load messages
#   fig.cap = "..."        add a figure caption
#
# Set defaults for the WHOLE document in a setup chunk near the top:

${fence}{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE)
${fence}

# Then knit:
#   - Click the "Knit" button in RStudio, OR
#   - rmarkdown::render("report.Rmd")
#   - Change  output: pdf_document  in the YAML to get a PDF instead.

Your turn. Fill in the TODO blanks, save as report.Rmd, and knit it.

# 🎯 YOUR TURN — fill in the blanks, save as report.Rmd, then Knit in RStudio.

---
title: "My First Report"
author: "TODO: your name"
output: html_document
---

# Sales Summary

${fence}{r}
sales <- c(100, 120, 90, 140)
# print the total with sum(sales)
sum(sales)
${fence}

The highest sale was `r max(sales)` units.

${fence}{r, echo=FALSE}
# echo=FALSE hides this code but still shows the bar plot
barplot(sales, main = "Sales by Month")
${fence}

# 👉 Click "Knit" in RStudio. You should get an HTML page with a
#    heading, the total (450), an inline max (140), and a bar chart
#    whose code is hidden because of echo=FALSE.

Mini-Challenge: A Reproducible Report

Assemble a complete mini-report from the spec: YAML, a setup chunk, a data frame, an inline total, and a captioned plot. Then change one number and re-knit to feel the power of reproducibility.

# 🎯 MINI-CHALLENGE: a reproducible mini-report.
#
# Create report.Rmd that knits to HTML and contains:
#
# 1. A YAML header with a title, your name, and output: html_document.
# 2. A setup chunk (include=FALSE) that sets echo = FALSE globally.
# 3. A chunk that builds this data frame:
#       df <- data.frame(month = month.abb[1:4], rev = c(50, 65, 40, 80))
# 4. An inline sentence stating the total revenue using `r sum(df$rev)`.
# 5. A chunk that plots revenue:  barplot(df$rev, names.arg = df$month)
# 6. fig.cap = "Quarterly revenue" on that plotting chunk.
#
# Knit it. Re-run after changing one number and watch EVERY figure
# (table, inline total, chart) update automatically — that's the win.

# write your .Rmd here

Common Errors (and the fix)

Pro Tips

📋 Quick Reference — R Markdown

TaskSyntax
Output formatoutput: html_document
Open a code chunk```{r}
Inline R`r mean(x)`
Hide code```{r, echo=FALSE}
Global optionsknitr::opts_chunk$set(...)
Render from codermarkdown::render("report.Rmd")

🎉 Lesson Complete!

Practice quiz

What lives in the YAML header between the two --- lines?

  • The R code chunks
  • Document metadata like title, author, and output format
  • The bibliography
  • Only the page title

Answer: Document metadata like title, author, and output format. The YAML header sets title, author, date, and the output format.

How do you open an R code chunk in R Markdown?

  • <r>
  • Three backticks followed by {r}
  • #{r}
  • [[r]]

Answer: Three backticks followed by {r}. A chunk opens with three backticks then {r} and closes with three backticks.

What does the chunk option echo=FALSE do?

  • Runs the code but hides the source, showing only output
  • Skips running the chunk
  • Hides both code and output
  • Adds a caption

Answer: Runs the code but hides the source, showing only output. echo=FALSE hides the source code while still showing the result.

What does eval=FALSE do to a chunk?

  • Hides the output
  • Hides the code
  • Shows the code but does not run it
  • Caches the chunk

Answer: Shows the code but does not run it. eval=FALSE displays the code without executing it.

What does include=FALSE do?

  • Shows code but not output
  • Shows output but not code
  • Adds the chunk to the table of contents
  • Runs the chunk but shows neither code nor output

Answer: Runs the chunk but shows neither code nor output. include=FALSE runs the chunk for side effects but hides code and output.

How do you embed a single computed value inside a sentence?

  • Inline R: a backtick, the letter r, an expression, a backtick
  • A {r} block
  • Using <<r>> tags
  • With paste() only

Answer: Inline R: a backtick, the letter r, an expression, a backtick. Inline R drops one value into prose with `r expr`.

Which function sets document-wide chunk defaults?

  • rmarkdown::render()
  • knitr::opts_chunk$set()
  • yaml::set()
  • options(chunk = ...)

Answer: knitr::opts_chunk$set(). knitr::opts_chunk$set() in a setup chunk sets global defaults.

How do you produce a PDF instead of HTML?

  • Rename the file to .pdf
  • Use eval=FALSE
  • Change output: to pdf_document in the YAML
  • Call print()

Answer: Change output: to pdf_document in the YAML. Set output: pdf_document in the YAML header (a LaTeX engine is needed).

Which function renders an .Rmd report from code?

  • rmarkdown::render("report.Rmd")
  • knit_now()
  • source("report.Rmd")
  • render.csv()

Answer: rmarkdown::render("report.Rmd"). rmarkdown::render() knits the document without the RStudio button.

Why prefer R Markdown over a script with pasted results?

  • It runs faster
  • It uses less memory
  • It needs no packages
  • It is reproducible: numbers regenerate from data each knit

Answer: It is reproducible: numbers regenerate from data each knit. Code, output, and prose live in one file, so re-knitting updates every figure.

Continue this course

Frequently asked questions

What is the YAML header at the top of an .Rmd file?

The block between the two --- lines is YAML metadata that controls the whole document. It sets the title, author, and date that appear at the top, and crucially the output format — html_document, pdf_document, or word_document — which tells knitr what kind of file to produce. You can also configure themes, a table of contents (toc: true), and parameters here. Think of it as the document's settings panel, written in simple key: value pairs.

What's the difference between a code chunk and inline R?

A code chunk is a block opened with ```{r} and closed with ```; knitr runs the whole block and inserts its output (text, table, or plot) into the report. Inline R, written as a backtick followed by r and an expression, drops a single computed value straight into a sentence — perfect for figures like 'sales rose by `r pct`%'. Use chunks for analysis and plots; use inline R so the prose numbers always match the data.

What do the echo, eval, and include chunk options do?

These control what readers see. echo=FALSE runs the code but hides the source, showing only results — ideal for a clean report. eval=FALSE shows the code but does not run it, useful for illustrating syntax. include=FALSE runs the chunk for its side effects (like loading packages) but shows neither the code nor its output. Set sensible defaults once in a setup chunk with knitr::opts_chunk$set(), then override per chunk as needed.

Why use R Markdown instead of just running a script and pasting results?

Because it is reproducible. In R Markdown the code, its output, and your narrative live in one file, so the numbers in your prose are generated from the data every time you knit. There is no copy-paste step to forget, and no risk of a chart showing last month's figures. Re-knit after the data changes and the entire document — tables, plots, and inline values — updates itself. That single source of truth is why R Markdown underpins reports, dashboards, slides, and even whole books.