Session 3: Reproducible Reports with Quarto

Published

28 09 2026

Modified

28 09 2026

Note

Monday, 28 September 2026, 09:00–11:15 · Room MAD 099

ImportantReport 1 is issued at the end of this session

Pricing the Barcelona hotel market — individual, pass/fail, and required for exam admission. Due Sunday 18 October, 23:59. The task sheet and the data go up on Moodle today; summary at the bottom of this page.

What this session is about

You have the answer already: among four-star hotels in Vienna, the central ones charge about €43 more per night. Today the board wants it as a document — two pages they can read in a meeting and forward to a colleague.

The obvious way to produce that document is to paste the table into Word and type the number into the first paragraph. That works until somebody changes the data, at which point the text and the table quietly start disagreeing with each other and nobody notices until the meeting.

Today is about the alternative: a document that computes its own numbers every time it is built, so it cannot contradict itself. Along the way: the YAML header, Markdown, chunk options, why the render is not your console, figures and tables you can refer to by name, citations — and the error messages you will meet while getting there.

ImportantPackages you need today

One new one, here — see New this session: i_am() and here() below for what it does:

install.packages("here")

Plus tidyverse and flextable from sessions 1 and 2. The optional messy-import task in the take-home also uses janitor, which you can install when you get there.

NoteYou have already written one of these

Your session 1 and session 2 files were Quarto documents. Today we stop treating Quarto as the thing that happens to be around the code, and use it properly.

Learning goals

  • Create a Quarto document, and read a YAML header well enough to write one
  • Format prose in Markdown — headings, emphasis, lists, links
  • Control what each chunk shows with echo, eval, include and label
  • Explain why the render is not your console, and why View(), install.packages() and setwd() therefore do not belong in a chunk
  • Use i_am() and here() for file paths that survive leaving your laptop, and say what a relative path is actually relative to
  • Put computed values into prose with inline R code — and never type a number into a sentence again
  • Give figures and tables labels and captions, and cross-reference them
  • Cite sources from a .bib file, including the dataset
  • Name the formats a .qmd can produce, and know which one this course wants
  • Read the four error messages that account for most failed renders

Slides

Open the slides in a separate tab

Open the slides in a separate tab in Chrome, add ?print-pdf to the end of the address, then print to PDF.

Materials

File Description
Exercise sheet The in-session exercise
hotels-vienna.csv The data, as in sessions 1 and 2
hotels-vienna-messy.csv The same data, badly exported — for the optional task
Slides The deck from the session
Live coding document The narrated code we wrote together
Exemplary solution Worked answers to the exercise

Data

The same Vienna hotels dataset as sessions 1 and 2 — the third and last session on it. Today the analysis is deliberately one you have already done, so that your attention goes on the document rather than on the question.

Békés and Kézdi (2021), licensed CC BY-NC-SA 4.0. Unmodified.

This one is modified. It carries the nine columns the analysis actually uses, re-exported the way a German Excel would export them: semicolons between fields, decimal commas, umlauts in ISO-8859-1 rather than UTF-8, column headers with spaces and brackets, and k.A. written where a guest rating is missing.

No value was changed — every one of those nine columns round-trips back to the original, which is what the optional task asks you to demonstrate. Adapted from Békés and Kézdi (2021) and shared under the same CC BY-NC-SA 4.0 licence.

New this session: i_am() and here()

Until now an RStudio project plus a relative path has been enough. From today, paths go through the here package — and every document starts by saying where it is:

library(here)
i_am("session03.qmd")        # where this document sits in the project

hotels <- read_csv(here("data", "hotels-vienna.csv"))

here() builds paths from the top of your project, so the same line works on your laptop, on mine, and on a marker’s. i_am() tells it where that top is instead of letting it search — which is the difference between a path that is checked and one that merely has not failed yet.

Install the package once if you have not already:

install.packages("here")
ImportantFrom today: both lines, in every document

here::i_am() above, here() in every path. All semester, and Report 1 asks for both. Two lines, and file paths stop being a source of failure.

WarningIf here() cannot find your data

The problem is almost never here(). It is that you opened the .qmd file directly instead of opening the project. Close everything, open applied-data-science.Rproj, and try again.

With here::i_am() in place you get told this immediately, by name, instead of discovering it at whichever read_csv() happens to run first.

The question we answer

Not a new one about hotels — a new one about documents:

How do you write an analysis down so that it still gives the right answer after somebody changes the data?

Two places, both uncomfortable.

The first: every number in a report should be computed, not typed. That sounds like a style preference until you change one filter and watch six numbers move at once — four of which you would have missed by hand.

The second is worse. We defined “central” as within one kilometre and got a premium of about €43. Split that first kilometre in half and the step between the two innermost bands is about €21. Nobody made a mistake; they are different questions. A reader given only the number cannot tell that a boundary was ever chosen. A reader given the document with its code can move it themselves.

That is the actual argument for reproducibility, and it is why all three reports are submitted as source plus output.

Take-home until session 4

Important
  1. Report 1 — start it this week, not in the third week
  2. Read Wickham et al. (2023), ch. 28 “Quarto” — about 40 minutes, and it covers everything on the exercise checklist
  3. Optional but genuinely useful: the messy import task on the exercise sheet. Real data arrives in that state more often than not.
  4. Also optional, and worth starting in the background: the PDF task at the end of the exercise sheet. HTML is all this course requires, but the LaTeX installation is easier to run one evening than in a seminar room.
  5. If anything from the first three sessions felt shaky, this is the time
WarningTwo weeks with no class

There is no session on 5 October and 12 October. Report 1 will not take both weeks. If the R or the statistics has been uncomfortable so far, work through First steps in R (Gräbner-Radkowitsch 2026a) or the statistics recap track (Gräbner-Radkowitsch 2026b) now. From session 5 the course stops revisiting the basics.

Session 4 is Git and GitHub — version control, entirely through the RStudio interface, with no command line.

Report 1

ImportantThe essentials
Task Pricing the Barcelona hotel market
Task sheet on Moodle, with the data and a separate hints document, from today
Issued end of this session, 28 September
Due Sunday 18 October, 23:59
Form individual, pass/fail — required for exam admission
Submit via Moodle: the rendered report and a zip of your project folder
Debrief session 4

Same structure as today’s exercise, on a city you have not seen: do the Vienna prices tell you anything about what a hotel in central Barcelona could charge? The full task description, the data and the assessment criteria are on Moodle. The Reports page here carries the deadlines and the rules that apply to all three.

Because a rendered HTML file is a claim, and the project is the evidence. Your report has to reproduce: I unzip your folder, open the .Rproj, restart R, render — and it has to give me your document, on my machine, without edits.

That is not an administrative hurdle. It is the one thing today’s session is about, and it is the difference between an analysis somebody can check and one they have to believe.

You can guarantee this half yourself in two minutes: unzip your own submission into an empty folder somewhere else and render it from there.

Going further

Before you submit anything in this course, it should:

  • render to HTML, from a restarted R session
  • contain no typed numbers in the prose
  • give every figure and table a label and a caption, and refer to them by name
  • cite its sources, data included
  • declare its location with i_am() and read its data with here()
  • show no warnings or package start-up messages
  • render on a machine that is not yours

References

Békés, G. and Kézdi, G. (2021) Data analysis for business, economics, and policy, Cambridge: Cambridge University Press, available at https://gabors-data-analysis.com/.
Gräbner-Radkowitsch, C. (2026a) First steps in R, 16 June 2026, Method and Inquiry, available at https://euf-methodology-hub.netlify.app/resources/first-steps-in-r (accessed August 2026).
Gräbner-Radkowitsch, C. (2026b) Learning track: A recap of undergraduate statistics, 14 June 2026, Method and Inquiry, available at https://euf-methodology-hub.netlify.app/tracks/statistics-recap (accessed August 2026).
Wickham, H., Çetinkaya-Rundel, M. and Grolemund, G. (2023) R for data science: Import, tidy, transform, visualize, and model data, 2nd edition., Beijing et al.: O’Reilly, available at https://r4ds.hadley.nz/.