ggplot(hotels, aes(x = distance, y = price)) +
geom_point() +
theme_classic()Exercise: your first report
Session 1 β Applied Data Science 2026
Add + theme_classic() to any ggplot(). It strips out the grey background and the clutter, and it costs you nothing:
Use it on everything you make today. theme_minimal() and theme_bw() are two other good ones β try them and pick the one you like.
Your firm is opening a hotel in Vienna. You have data on 428 competitors. Your manager wants one chart that tells them something they did not already know about how hotel rooms are priced in this city.
Alone or in pairs. Ask for help early β being stuck for a few minutes is normal, being stuck for much longer is a waste of your time.
1 Part 1 β Check your project is set up properly
You saw this during the live coding. Getting the structure right is not mere bureaucracy β it is what makes an analysis reproducible for your future-you three months from today, and it helps you not to get lost!
Whether you keep one project for the whole course or start a new one each session is your call; both work. What has to be true either way is that your .qmd sits at the top of a project with data/ next to it β that is what makes data/hotels-vienna.csv work.
To build your project:
- In RStudio: File β New Project β New Directory β New Project
- Name it
applied-data-science-s01or something similar - Put it somewhere sensible β not Downloads, not Desktop
- Click Create Project
You will know it worked when the top-right corner of RStudio shows the project name and the Files pane shows your new folder. If it does not, something went wrong.
1.1 The folder structure
Create any missing folders with the New Folder button in the Files pane (bottom right), and make sure the data is in data/:
applied-data-science/
βββ applied-data-science.Rproj β created for you; never edit it
βββ data/ β raw data, read-only. Never edit by hand.
β βββ hotels-vienna.csv β download from the session page
βββ R/ β .R scripts (we start using this in session 2)
βββ Output/ β rendered reports, exported figures and tables
βββ session01.qmd β your report for today
1.2 Create your report
- File β New File β Quarto Document, save it as
session01.qmdin the project root - Give it a YAML header with a title, your name and
format: html
1.3 Load the data
library(tidyverse)
hotels <- read_csv("data/hotels-vienna.csv")2 Part 2 β Get your bearings
Answer these three questions. Write each answer as one sentence of text underneath the chunk that produced it.
- How many hotels are in the dataset, and how many variables describe each one?
nrow(hotels)
ncol(hotels)- What is the median price per night, and what is the cheapest room?
summary(hotels$price)- How many hotels are there of each
accommodation_type?
count(hotels, accommodation_type)count() is not found
count() is a tidyverse function. If R says it cannot find it, you forgot library(tidyverse).
3 Part 3 β Make your chart
Build one chart. It must not be distance against price β we did that together.
Pick a question first, then a chart. Some options:
| Question | Try |
|---|---|
| How are prices distributed? | geom_histogram() on price |
| Do more stars cost more? | geom_violin() or geom_boxplot(), factor(stars) on x, price on y |
| Do guest ratings track price? | geom_point() with rating and price |
| Are apartments cheaper than hotels? | geom_violin() or geom_boxplot() with accommodation_type |
| Where are the hotels? | geom_histogram() on distance |
The skeleton is always the same:
ggplot(data = hotels, mapping = aes(x = ___, y = ___)) +
geom____()Then label it properly:
labs(
x = "...",
y = "...",
title = "..."
)4 Part 4 β Write it up
Underneath your chart, write three sentences:
- What does the chart show?
- What surprised you?
- What could make it misleading? β the most important one
Then render to HTML.
5 Part 5 β If you finish early
Pick any of these:
Add a second chart that splits your first one by a third variable β use
facet_wrap(~ accommodation_type)Remove the problems we found and see whether your chart changes:
hotels_clean <- hotels |>
filter(city_actual == "Vienna", price < 1000)How many rows did you lose, and did your finding survive?
- Investigate this, which is stranger than it looks:
hotels_clean |>
group_by(stars) |>
summarise(n = n(), median_price = median(price))Two-star places have a higher median price than three-star ones. That cannot be right. Something other than the star rating is mixed into this comparison β find it.
Ask what kinds of place carry a two-star rating: hotels_clean |> filter(stars == 2) |> count(accommodation_type)
- Set
#| echo: falseon your chart chunk, re-render, and see what changes