Commit 0e62aad4 authored by 7f9d4a2f9f536fc2da1beb7df3382bb3's avatar 7f9d4a2f9f536fc2da1beb7df3382bb3
parents 758aa33b a0c36dd2
# Journal de bord – MOOC Recherche Reproductible
## Jour 1
- Découverte de R Markdown
- Différence entre Jupyter, RStudio et Org-mode
### Données
- Date : 19/12/2025
- Temps : nuageux
- Temps de travail : 1h30
# Partie 1
## Ce que j’apprends
- Utilisation de GitLab
- Écriture en Markdown
*texte en italique*
**texte en gras**
Lien vers le MOOC :
https://app-learninglab.inria.fr/moocrr/
1. premier point
2. second point
```python
print("Bonjour le monde")
--- ---
title: "Votre titre" title: "À propos du calcul de pi"
author: "Votre nom" author: "Arnaud Legrand"
date: "La date du jour" date: "25 juin 2018"
output: html_document output: html_document
--- ---
En demandant à la lib maths
Mon ordidnateur m'indique que π vaut approximativement
```{r setup, include=FALSE} ```{r}
knitr::opts_chunk$set(echo = TRUE) pi
``` ```
## En utilisant la méthode des aiguillesde Buffon
## Quelques explications Mais calculé avec la méthode dess aiguiles de Buffon , on obtienrait comme approximation:
```{r}
Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez <http://rmarkdown.rstudio.com>. set.seed(42)
N = 100000
Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: x = runif(N)
theta = pi/2*runif(N)
```{r cars} 2/(mean(x+sin(theta)>1))
summary(cars)
``` ```
## Avec un argument “fréquentiel” de surface
Et on peut aussi aisément inclure des figures. Par exemple: Sinon, une méthode plus simple à comprendre et ne faisant pas intervenir d’appel à la fonction sinus se base sur le fait que si $X\sim U(0,1)$ et $Y\sim U(0,1)$ alors $P[X^2+Y^2\le 1]=\pi/4$ (voir méthode de Monte Carlo sur Wikipedia). Le code suivant illustre ce fait:
```{r}
```{r pressure, echo=FALSE} set.seed(42)
plot(pressure) N = 1000
``` df = data.frame(X = runif(N), Y = runif(N))
df$Accept = (df$X**2 + df$Y**2 <=1)
Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. library(ggplot2)
ggplot(df, aes(x=X,y=Y,color=Accept)) + geom_point(alpha=.2) +
Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. coord_fixed() + theme_bw()
---
Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel. \ No newline at end of file
--- ---
title: "Votre titre" title: "Statistiques descriptives"
author: "Votre nom" author: "Votre nom"
date: "La date du jour" date: "19 décembre 2025"
output: html_document output: html_document
--- ---
```{r}
data <- c(
```{r setup, include=FALSE} 14.0, 7.6, 11.2, 12.8, 12.5, 9.9, 14.9, 9.4, 16.9, 10.2,
knitr::opts_chunk$set(echo = TRUE) 14.9, 18.1, 7.3, 9.8, 10.9, 12.2, 9.9, 2.9, 2.8, 15.4,
``` 15.7, 9.7, 13.1, 13.2, 12.3, 11.7, 16.0, 12.4, 17.9, 12.2,
16.2, 18.7, 8.9, 11.9, 12.1, 14.6, 12.1, 4.7, 3.9, 16.9,
## Quelques explications 16.8, 11.3, 14.4, 15.7, 14.0, 13.6, 18.0, 13.6, 19.9, 13.7,
17.0, 20.5, 9.9, 12.5, 13.2, 16.1, 13.5, 6.3, 6.4, 17.6,
Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez <http://rmarkdown.rstudio.com>. 19.1, 12.8, 15.5, 16.3, 15.2, 14.6, 19.1, 14.4, 21.4, 15.1,
19.6, 21.7, 11.3, 15.0, 14.3, 16.8, 14.0, 6.8, 8.2, 19.9,
Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: 20.4, 14.6, 16.4, 18.7, 16.8, 15.8, 20.4, 15.8, 22.4, 16.2,
20.3, 23.4, 12.1, 15.5, 15.4, 18.4, 15.7, 10.2, 8.9, 21.0
```{r cars} )
summary(cars)
mean(data)
sd(data) # écart-type corrigé (par défaut en R)
min(data)
median(data)
max(data)
``` ```
Et on peut aussi aisément inclure des figures. Par exemple:
```{r pressure, echo=FALSE}
plot(pressure)
```
Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles.
Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter.
Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel.
--- ---
title: "Votre titre" title: "Affichage graphique des données"
author: "Votre nom" author: "Votre nom"
date: "La date du jour" date: "19 décembre 2025"
output: html_document output: html_document
--- ---
```{r}
data <- c(
```{r setup, include=FALSE} 14.0, 7.6, 11.2, 12.8, 12.5, 9.9, 14.9, 9.4, 16.9, 10.2,
knitr::opts_chunk$set(echo = TRUE) 14.9, 18.1, 7.3, 9.8, 10.9, 12.2, 9.9, 2.9, 2.8, 15.4,
``` 15.7, 9.7, 13.1, 13.2, 12.3, 11.7, 16.0, 12.4, 17.9, 12.2,
16.2, 18.7, 8.9, 11.9, 12.1, 14.6, 12.1, 4.7, 3.9, 16.9,
## Quelques explications 16.8, 11.3, 14.4, 15.7, 14.0, 13.6, 18.0, 13.6, 19.9, 13.7,
17.0, 20.5, 9.9, 12.5, 13.2, 16.1, 13.5, 6.3, 6.4, 17.6,
Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez <http://rmarkdown.rstudio.com>. 19.1, 12.8, 15.5, 16.3, 15.2, 14.6, 19.1, 14.4, 21.4, 15.1,
19.6, 21.7, 11.3, 15.0, 14.3, 16.8, 14.0, 6.8, 8.2, 19.9,
Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: 20.4, 14.6, 16.4, 18.7, 16.8, 15.8, 20.4, 15.8, 22.4, 16.2,
20.3, 23.4, 12.1, 15.5, 15.4, 18.4, 15.7, 10.2, 8.9, 21.0
```{r cars} )
summary(cars)
``` # 1. Sequence plot
plot(data, type = "b",
Et on peut aussi aisément inclure des figures. Par exemple: xlab = "Index",
ylab = "Valeur",
```{r pressure, echo=FALSE} main = "Sequence plot des données")
plot(pressure)
``` # 2. Histogramme
hist(data,
Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. breaks = 10,
col = "lightgray",
Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. main = "Histogramme des données",
xlab = "Valeur")
Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel.
date,study_minutes,mood,weather,notes
2025-12-19,60,7,cloudy,"Started module 2 exo4"
2025-12-20,45,6,rain,"Worked on markdown and Rmd"
2025-12-21,90,8,sunny,"Did plots and stats"
--- ---
title: "Votre titre" title: "Journal de bord — analyse"
author: "Votre nom" author: "Votre nom"
date: "La date du jour" date: "19 décembre 2025"
output: html_document output: html_document
--- ---
```{r}
df <- read.csv("daily_data.csv", stringsAsFactors = FALSE)
df$date <- as.Date(df$date)
# Statistiques de base
summary(df)
```{r setup, include=FALSE} # Exemple : moyenne du temps d'étude
knitr::opts_chunk$set(echo = TRUE) mean(df$study_minutes)
```
## Quelques explications
Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez <http://rmarkdown.rstudio.com>.
Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante:
```{r cars}
summary(cars)
```
Et on peut aussi aisément inclure des figures. Par exemple:
```{r pressure, echo=FALSE} # Graphique : évolution du temps d'étude
plot(pressure) plot(df$date, df$study_minutes, type="b",
xlab="Date", ylab="Minutes d'étude",
main="Temps d'étude par jour")
``` ```
\ No newline at end of file
Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles.
Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter.
Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel.
...@@ -29,6 +29,43 @@ Nous commençons donc par charger ces données: ...@@ -29,6 +29,43 @@ Nous commençons donc par charger ces données:
data = read.csv("shuttle.csv",header=T) data = read.csv("shuttle.csv",header=T)
data data
``` ```
```{r}
# =========================
# Correction de l'analyse
# =========================
# ERREUR HISTORIQUE :
# Les analyses initiales filtraient les vols avec Malfunction > 0,
# supprimant ainsi les vols sans incident (zéros), ce qui biaise
# totalement l'estimation d'une probabilité.
# On conserve donc TOUS les vols.
# Création d'une variable binaire correcte :
# 1 = au moins un joint défaillant, 0 = aucun incident
data$incident <- as.integer(data$Malfunction > 0)
# Visualisation correcte : tous les vols
plot(data$Temperature, data$incident, pch = 19,
xlab = "Température (°F)",
ylab = "Incident (0/1)",
main = "Risque de défaillance vs température (tous les vols)")
# Régression logistique correcte
fit_incident <- glm(incident ~ Temperature, data = data, family = binomial())
summary(fit_incident)
# Courbe de probabilité estimée
tgrid <- data.frame(Temperature = seq(min(data$Temperature),
max(data$Temperature),
length.out = 200))
tgrid$p <- predict(fit_incident, newdata = tgrid, type = "response")
plot(data$Temperature, data$incident, pch = 19,
xlab = "Température (°F)",
ylab = "Incident (0/1)",
main = "Probabilité estimée d'incident selon la température")
lines(tgrid$Temperature, tgrid$p, lwd = 2)
Le jeu de données nous indique la date de l'essai, le nombre de joints Le jeu de données nous indique la date de l'essai, le nombre de joints
toriques mesurés (il y en a 6 sur le lançeur principal), la toriques mesurés (il y en a 6 sur le lançeur principal), la
...@@ -36,15 +73,11 @@ température (en Farenheit) et la pression (en psi), et enfin le ...@@ -36,15 +73,11 @@ température (en Farenheit) et la pression (en psi), et enfin le
nombre de dysfonctionnements relevés. nombre de dysfonctionnements relevés.
# Inspection graphique des données # Inspection graphique des données
Les vols où aucun incident n'est relevé n'apportant aucun information Les sans incident (Malfunction = 0) sont essentiels : ils indiquent à quelles
sur l'influence de la température ou de la pression sur les températures *aucun* problème n’est observé. Les exclure biaise l’analyse et
dysfonctionnements, nous nous concentrons sur les expériences où au conduit à sous-estimer le risque aux basses températures.
moins un joint a été défectueux.
```{r}
data = data[data$Malfunction>0,]
data
```
Très bien, nous avons une variabilité de température importante mais Très bien, nous avons une variabilité de température importante mais
la pression est quasiment toujours égale à 200, ce qui devrait la pression est quasiment toujours égale à 200, ce qui devrait
......
...@@ -43,8 +43,13 @@ Voici l'explication des colonnes donnée sur le [sur le site d'origine](https:// ...@@ -43,8 +43,13 @@ Voici l'explication des colonnes donnée sur le [sur le site d'origine](https://
La première ligne du fichier CSV est un commentaire, que nous ignorons en précisant `skip=1`. La première ligne du fichier CSV est un commentaire, que nous ignorons en précisant `skip=1`.
### Téléchargement ### Téléchargement
```r
```{r} ```{r}
data = read.csv(data_url, skip=1) local_file <- "incidence-PAY-3.csv"
if (!file.exists(local_file)) {
download.file(data_url, destfile = local_file, mode = "wb")
}
data <- read.csv(local_file, skip = 1)
``` ```
Regardons ce que nous avons obtenu: Regardons ce que nous avons obtenu:
......
--- import os
title: "Votre titre" import re
author: "Votre nom" import csv
date: "La date du jour" from datetime import date
output: html_document import pandas as pd
---
DATA_PATH = r"C:\Users\nargi\Downloads\inc-25-PAY.csv"
```{r setup, include=FALSE} if not os.path.exists(DATA_PATH):
knitr::opts_chunk$set(echo = TRUE) raise FileNotFoundError(f"File not found: {DATA_PATH}")
```
## Quelques explications # ------------------------------------------------------------
# 1) Load Sentinelles CSV robustly (skip broken metadata / find real header)
# ------------------------------------------------------------
with open(DATA_PATH, "r", encoding="utf-8", errors="replace") as f:
lines = f.read().splitlines()
Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez <http://rmarkdown.rstudio.com>. # Find header line: contains letters + separators and NOT just the metadata blob
header_idx = None
for i, ln in enumerate(lines):
if not ln.strip():
continue
if ln.lstrip().startswith("#"):
continue
low = ln.lower()
if ((";" in ln) or ("," in ln) or ("\t" in ln) or ("|" in ln)) and re.search(r"[A-Za-z_]", ln):
header_idx = i
break
Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: if header_idx is None:
raise ValueError("Could not find a header row (CSV table) in the file.")
```{r cars} # detect delimiter from that header line
summary(cars) header_line = lines[header_idx]
``` try:
dialect = csv.Sniffer().sniff(header_line, delimiters=[",", ";", "\t", "|"])
sep = dialect.delimiter
except Exception:
sep = ";" # common in FR exports
Et on peut aussi aisément inclure des figures. Par exemple: content = "\n".join(lines[header_idx:])
df = pd.read_csv(pd.io.common.StringIO(content), sep=sep, engine="python", on_bad_lines="skip")
```{r pressure, echo=FALSE} df = df.loc[:, ~df.columns.astype(str).str.match(r"^Unnamed")]
plot(pressure) if df.empty:
``` raise ValueError("Parsed dataframe is empty. The file may not contain tabular data.")
Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. # ------------------------------------------------------------
# 2) Identify week column and incidence column
# ------------------------------------------------------------
def score_week_col(s: pd.Series) -> float:
x = s.dropna().astype(str).str.strip().head(200)
if x.empty:
return 0.0
patterns = [
r"^\d{6}$", # YYYYWW
r"^\d{4}-?W\d{1,2}$", # YYYY-WW or YYYYWww
r"^\d{4}s\d{1,2}$", # YYYYsWW
]
return max(x.str.match(p, case=False).mean() for p in patterns)
Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. week_col = max(df.columns, key=lambda c: score_week_col(df[c]))
if score_week_col(df[week_col]) < 0.3:
raise ValueError(f"Could not detect week column. Columns: {list(df.columns)}")
Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel. # incidence column: prefer inc100 like in your R code, else pick best numeric column containing 'inc'
lower_to_orig = {str(c).strip().lower(): c for c in df.columns}
inc_col = None
for k in ["inc100", "inc_100", "incidence100", "incidence_100"]:
if k in lower_to_orig:
inc_col = lower_to_orig[k]
break
def to_num(s: pd.Series) -> pd.Series:
return pd.to_numeric(s.astype(str).str.replace(",", ".", regex=False), errors="coerce")
if inc_col is None:
cands = []
for c in df.columns:
if c == week_col:
continue
if "inc" in str(c).lower():
coerced = to_num(df[c])
if coerced.notna().sum() > 0:
df[c] = coerced
cands.append(c)
if not cands:
# fallback: any numeric column
for c in df.columns:
if c == week_col:
continue
coerced = to_num(df[c])
if coerced.notna().sum() > 0:
df[c] = coerced
cands.append(c)
if not cands:
raise ValueError("Could not find any numeric incidence column.")
inc_col = max(cands, key=lambda c: df[c].var(skipna=True))
df[inc_col] = to_num(df[inc_col])
# ------------------------------------------------------------
# 3) Convert ISO week -> Monday date (like your R parse_iso_8601 approach)
# ------------------------------------------------------------
def week_to_monday(w) -> pd.Timestamp:
w = str(w).strip()
m = re.match(r"^(?P<y>\d{4})(?P<w>\d{2})$", w) # YYYYWW
if m:
y = int(m.group("y")); ww = int(m.group("w"))
return pd.Timestamp(date.fromisocalendar(y, ww, 1))
m = re.match(r"^(?P<y>\d{4})-?W(?P<w>\d{1,2})$", w, flags=re.IGNORECASE) # YYYYWww
if m:
y = int(m.group("y")); ww = int(m.group("w"))
return pd.Timestamp(date.fromisocalendar(y, ww, 1))
m = re.match(r"^(?P<y>\d{4})s(?P<w>\d{1,2})$", w, flags=re.IGNORECASE) # YYYYsww
if m:
y = int(m.group("y")); ww = int(m.group("w"))
return pd.Timestamp(date.fromisocalendar(y, ww, 1))
ts = pd.to_datetime(w, errors="coerce")
if pd.isna(ts):
raise ValueError(f"Unrecognized week format: {w}")
return ts
df["date"] = df[week_col].apply(week_to_monday)
df = df.sort_values("date").reset_index(drop=True)
# ------------------------------------------------------------
# 4) Define epidemic year EXACTLY as: (Sep 1 N-1, Sep 1 N]
# We label it by the END year N (like your R variable 'annee')
# ------------------------------------------------------------
def season_end_year(d: pd.Timestamp) -> int:
# If date is strictly after Sep 1 of its calendar year => belongs to season ending next year
sep1 = pd.Timestamp(f"{d.year}-09-01")
return d.year + 1 if d > sep1 else d.year
df["annee"] = df["date"].apply(season_end_year)
# Keep reasonable years (at least one full season)
valid_years = sorted(df["annee"].unique())
# ------------------------------------------------------------
# 5) Compute BOTH metrics per epidemic year:
# - cumulative = sum(inc100)
# - peak = max(inc100)
# ------------------------------------------------------------
annual = (
df.groupby("annee", as_index=False)
.agg(
incidence_sum=(inc_col, "sum"),
incidence_peak=(inc_col, "max"),
n_weeks=(inc_col, "count"),
first_date=("date", "min"),
last_date=("date", "max"),
)
.sort_values("annee")
)
# strongest/weakest by SUM
strong_sum = annual.loc[annual["incidence_sum"].idxmax(), ["annee", "incidence_sum"]]
weak_sum = annual.loc[annual["incidence_sum"].idxmin(), ["annee", "incidence_sum"]]
# strongest/weakest by PEAK
strong_peak = annual.loc[annual["incidence_peak"].idxmax(), ["annee", "incidence_peak"]]
weak_peak = annual.loc[annual["incidence_peak"].idxmin(), ["annee", "incidence_peak"]]
print(f"✅ Loaded: {DATA_PATH}")
print(f"✅ Separator: {repr(sep)}")
print(f"✅ Week column: {week_col}")
print(f"✅ Incidence column: {inc_col}")
print(f"✅ Date range: {df['date'].min().date()} -> {df['date'].max().date()}")
print("\n--- Epidemic year definition: (Sep 1 N-1, Sep 1 N] labeled by N ---\n")
print("RESULTS using CUMULATIVE incidence (SUM over the epidemic year):")
print(f" Strongest: year {int(strong_sum['annee'])} | sum = {strong_sum['incidence_sum']:.3f}")
print(f" Weakest: year {int(weak_sum['annee'])} | sum = {weak_sum['incidence_sum']:.3f}")
print("\nRESULTS using PEAK incidence (MAX weekly over the epidemic year):")
print(f" Strongest: year {int(strong_peak['annee'])} | peak = {strong_peak['incidence_peak']:.3f}")
print(f" Weakest: year {int(weak_peak['annee'])} | peak = {weak_peak['incidence_peak']:.3f}")
print("\n--- Sanity check (first 12 epidemic years) ---")
print(annual.head(12).to_string(index=False))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment