Comment réorganiser des Données agglomérées avec une colonne par année
En langage R
L'essentiel de cette page
Les bonnes pratiques exigent que, dans l'analyse de données, l'on mette une seule colonne par variable. Pourtant, bien souvent, celui qui prépare ses données trouvera pratique d'assembler ses valeurs en ajoutant une colonne par année (ex : poids2024, poids2025, poids2026) alors qu'il faudra une seule colonne pour cette variable et une pour l'année.
Voici un code qui permet de redonner une forme exploitable à un jeu de données mal organisé de cette façon.
Partons d'un exemple...
Des données pour l'exemple
Ce code permet par un simple copier-coller de générer un jeu de données où le poids de 4 personnes a été collectées de 2024 à 2026. Leurs taille n'a été relevée que sur 2024 et 2026 (pas 2025). Une tentative d'analyse a été menée en comparant les poids de 2026 et 2024 dans une colonne Poids2026-2024.
On notera tout de suite des erreurs à ne pas.
Il ne faut jamais mettre une colonne pour chaque année d'une variable
Il ne faut pas commencer à analyser les données dans le tableur avec une colonne Poids2026-2024.
Le vrai tableau devrait ressembler à cela :
# Code pour générer cet exemple (à copier-coller)
df <- data.frame(Noms=c("Marcel","Julia","Rose","Joseph"),
Poids2024=round(rnorm(4,75,6),0))
df <- cbind(df,Poids2025=round(df$Poids2024*rnorm(4,1,0.1),0))
df <- cbind(df,Poids2026=round(df$Poids2025*rnorm(4,1,0.1),0))
df <- cbind(df,"Poids2026-2024"=df$Poids2026-df$Poids2024)
df <- cbind(df,Tailles2024=round(rnorm(4,170,12),0))
df <- cbind(df,Tailles2026=round(df$Tailles2024*rnorm(4,1,0.01),0))
print(df)
Des données pour l'exemple
# 1. Éliminer les colonnes indésirables
eliminate_patterns <- "(\\D+\\d{2,4}-\\d{2,4})"
cols_to_eliminate <- grep(eliminate_patterns, colnames(df), value = TRUE) # Vérification des colonnes à éliminer print(cols_to_eliminate)
data_filtered <- df[, !colnames(df) %in% cols_to_eliminate]
# Vérification du dataframe filtré
print(data_filtered)
# 2. Sélectionner les colonnes correspondant aux variables d'intérêt (les colonnes avec des années à la fin)
cols_variable <- grep("\\d{2,4}$", colnames(data_filtered), value = TRUE)
# Extraire les entités (colonnes non correspondant aux variables d'intérêt) - ici une seule colonne, les noms
entities <- data.frame(data_filtered[,1] )
3 # Extraire les années et les noms de variables
years <- as.numeric(sub(".*(\\d{2,4})$", "\\1", colnames(data_filtered[, cols_variable])))
years[years < 100] <- years[years < 100] + 2000
# Ajuster pour les années à 2 chiffres
variable_names <- sub("\\d{2,4}$", "", colnames(data_filtered[, cols_variable]))
indices_variable <- grep("\\d{2,4}$", colnames(data_filtered))
4 # Initialiser data_final avec les colonnes d'entités correctement
data_final <- data.frame(rep(sort(unique(years)),each=nrow(entities)))
colnames(data_final)<-"Année"
for (i in 1:ncol(entities)) {
data_final[,i+1] <- rep(entities[,i],length(unique(years)))
colnames(data_final)[ncol(data_final)]<- colnames(entities)[i]
}
# Ajouter les colonnes de variables à data_final
for (i in unique(variable_names)) {
variable <- c()
for (j in sort(unique(years))) {
temp <- data_filtered[, indices_variable[variable_names == i & years == j]]
if (length(temp) == 0) {
temp <- rep(NA, nrow(entities))
}
variable <- c(variable, temp)
}
data_final <- cbind(data_final, variable)
colnames(data_final)[ncol(data_final)] <- i
}