df <- "https://lbelzile.github.io/multi/files/data/MarathonBerlin2022.csv"
marathon <- read.csv(df, header = TRUE)Activité 2 - Manipulations et graphiques
Chargez les données
Manipulations
- Transformez les types de variables (temps, facteurs, entiers)
- Obtenez les noms associés aux codes des pays (codes du CIO)
- Transformez en valeurs manquantes
- les valeurs de sexe non déclarées
- les classements des personnes qui n’ont pas complété la course, ou qui ont été disqualifiées
- Retirez les variables
starttime,grosstimeetdivision - Créez un facteur
vaguereprésentant le temps de la vague de départ (starttime)
Graphiques
- Créez un diagramme à bande du nombre de participants par pays (10 premiers)
- Tracez un histogramme des temps de complétion du marathon en fonction du sexe de l’athlète
- Créez un diagramme spaghetti (ligne brisée) de la vitesse des 25 coureurs les plus rapides en fonction de la distance par intervalle de 5km (difficile).
Réponses
# Est-ce que les classements par genre sont uniques?
head(sort(table(marathon$position_gender), decreasing = TRUE))
– DSQ 11187 9840 10057 10094
727 53 5 5 4 4
# Réponse: DSQ pour disqualifiés, - pour manquants, plusieurs doublons
# Est-ce que le classement global est unique?
head(sort(table(marathon$position), decreasing = TRUE))
DNF 1 10 100 1000 10000
727 1 1 1 1 1
# Oui, mais 727 DNF (pas complété).library(dplyr, warn.conflicts = FALSE)
library(tidyr)
library(lubridate, warn.conflicts = FALSE)
library(countrycode)
berlin <- marathon |>
mutate( # transformer les variables
position = as.integer(
na_if(position, "DNF")
),
position_gender = as.integer(
replace_values(position_gender, c("–", "DSQ") ~ NA)
),
countrycode = case_when(nchar(country) == 3L ~ country, .default = NA),
country = recode_values(
countrycode,
from = countrycode::codelist$ioc,
to = countrycode::codelist$country.name.fr,
default = NA
),
sex = factor(na_if(sex, "-")),
bib = factor(bib),
category = factor(category),
vague = factor(substr(start_raw_time, 1, 5)),
half = na_if(half, "")
) |>
mutate(
start_raw_time = hms(na_if(start_raw_time, "–"), quiet = TRUE),
across(half:nettime, ~ as.duration(hms(na_if(.x, "–"), quiet = TRUE))),
) |>
# retirer les variables
select(
!c(
division, # pas utilisée
grosstime, # information déjà avec nettime
starttime # transformé en facteur (vague)
)
)# Graphique 1: Diagramme à bande des 10 pays principaux (nombre de coureurs)
library(ggplot2)
theme_set(theme_classic())
library(tinyplot)
tinytheme("clean2")
# Facteur, avec ordre par nombre
pays10 <- as.data.frame(
sort(with(berlin, table(country)), decreasing = TRUE)[10:1]
) |>
mutate(country = factor(country, levels = country, labels = country))
ggplot(
data = pays10,
mapping = aes(
y = country,
x = Freq
)
) +
geom_col() +
scale_x_continuous(limits = c(0, NA), expand = expansion()) +
labs(
y = "", x = "",
title = "nombre de participants par pays",
caption = "Marathon de Berlin (2022)"
)
plt(
Freq ~ country,
data = pays10,
type = "barplot",
main = "Nombre de participants par pays",
xlab = "",
ylab = "",
flip = TRUE,
cap = "Source: Marathon de Berlin, 2022"
)
# Graphique 2: vitesse par sexe
ggplot(
data = berlin |>
drop_na(sex) |>
mutate(sex = factor(
sex,
levels = c("F","M"),
labels = c("femmes","hommes"))),
mapping = aes(
x = nettime / 3600,
fill = sex,
)
) +
geom_histogram(bins = 30, alpha = 0.5) +
viridis::scale_fill_viridis(discrete = TRUE) +
scale_y_continuous(limits = c(0, NA), expand = expansion()) +
labs(fill = "sexe",
y = "décompte",
x = "temps de complétion du marathon (en heures)",
caption = "Marathon de Berlin (2022)"
) +
theme(legend.position = c(0.9,0.9))
plt(
~ I(as.numeric(nettime) / 3600) | sex,
data = berlin |>
filter(!is.na(sex)) |>
mutate(sex = factor(
sex,
levels = c("F","M"),
exclude = NA,
labels = c("femmes","hommes"))),
type = "histogram",
main = "temps de complétion du marathon (en heures)",
xlab = "",
legend = list("topright", title = "sexe"),
ylab = "décompte",
cap = "Source: Marathon de Berlin, 2022"
)
# Graphique 3: vitesses de passage du top 25
# Transformer les temps de passage en vitesse
berlin <- berlin |>
mutate(
V5 = 5 / as.numeric(X5k) * 3600,
V10 = 5 / as.numeric(X10k - X5k) * 3600,
V15 = 5 / as.numeric(X15k - X10k) * 3600,
V20 = 5 / as.numeric(X20k - X15k) * 3600,
V25 = 5 / as.numeric(X25k - X20k) * 3600,
V30 = 5 / as.numeric(X30k - X25k) * 3600,
V35 = 5 / as.numeric(X35k - X30k) * 3600,
V40 = 5 / as.numeric(X40k - X35k) * 3600,
Vmoy = 42.195 / as.numeric(nettime) * 3600,
) |>
mutate(across(starts_with("V", ignore.case = FALSE),
\(x) round(x, digits = 2)))
top25 <- berlin |>
select(position, starts_with("V", ignore.case = FALSE)) |>
select(!Vmoy) |>
filter(position <= 25) |>
tidyr::pivot_longer(
cols = tidyr::starts_with("V"),
names_to = "km",
names_prefix = "V",
values_to = "speed"
) |>
mutate(km = as.numeric(km))
plt(
x = speed ~ km | position,
type = "b",
xlab = "km",
ylab = "",
main = "Performance des 25 meilleurs coureurs",
sub = "Vitesse (km/h) par segment de 5km",
cap = "Source: Marathon de Berlin, 2022",
data = top25,
legend = FALSE
)
ggplot(
data = top25,
mapping = aes(
x = km,
group = factor(position),
col = factor(position),
y = speed
)
) +
geom_point(show.legend = FALSE) +
geom_line(show.legend = FALSE) +
labs(
x = "km",
y = "",
# col = "rang",
subtitle = "Vitesse (km/h) par segment de 5km",
title = "Performance des 25 meilleurs coureurs",
caption = "Source: Marathon de Berlin, 2022",
)