Chargement de packages pour les solutions utilisant des fonctions du
tidyverse :
library(dplyr)
library(tidyr)
airqualityLes premières questions vous feront encore manipuler les données
stockées dans le data frame airquality, inclus dans le
package datasets de l’installation de base de R. Il s’agit
d’observations de quantité d’ozone et de radiation solaire dans l’air de
New York pour chaque jour des mois de mai à septembre en 1973. Le data
frame comprend aussi des mesures de vitesse du vent et de
température.
str(airquality)
## 'data.frame': 153 obs. of 6 variables:
## $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ...
## $ Solar.R: int 190 118 149 313 NA NA 299 99 19 194 ...
## $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
## $ Temp : int 67 72 74 62 56 66 65 59 61 69 ...
## $ Month : int 5 5 5 5 5 5 5 5 5 5 ...
## $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
Créez une copie du data frame airquality et ajoutez à
cette copie une variable contenant le nom anglais du mois. Le vecteur
month.name provenant du package base de R, qui
contient les noms des mois en anglais en ordre chronologique, peut vous
être utile.
Voici un extrait et la structure de ce que vous devez obtenir :
air_quality[c(30, 48, 75, 110, 153), ]
## Ozone Solar.R Wind Temp Month Day Month.Name
## 30 115 223 5.7 79 5 30 May
## 48 37 284 20.7 72 6 17 June
## 75 NA 291 14.9 91 7 14 July
## 110 23 115 7.4 76 8 18 August
## 153 20 223 11.5 68 9 30 September
str(air_quality)
## 'data.frame': 153 obs. of 7 variables:
## $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ...
## $ Solar.R : int 190 118 149 313 NA NA 299 99 19 194 ...
## $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
## $ Temp : int 67 72 74 62 56 66 65 59 61 69 ...
## $ Month : int 5 5 5 5 5 5 5 5 5 5 ...
## $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Month.Name: chr "May" "May" "May" "May" ...
# Création d'une copie du jeu de données
air_quality <- airquality
# Création et ajout de la nouvelle variable
air_quality$Month.Name <- month.name[air_quality$Month]
# Le résultat d'une extraction avec l'opérateur [ et un vecteur
# de positions fourni en argument (ici air_quality$Month) est
# de la même longueur que le vecteur de positions. Ce vecteur peut
# contenir des positions répétées, auquel cas la valeur correspondante
# dans l'objet d'où sont extrait des données (ici month.name) est
# répétée autant de fois.
# Autres façons d'ajouter la nouvelle variable à air_quality
air_quality[["Month.Name"]] <- month.name[air_quality$Month]
# ou encore
air_quality <- cbind(
air_quality,
Month.Name = month.name[air_quality$Month]
)
# ou encore
air_quality <- transform(air_quality, Month.Name = month.name[Month])Ajoutez à votre copie de airquality créée à la question
précédente une autre variable contenant la date complète sous la classe
Date de R (les données ont été recueillies en 1973).
Voici un extrait et la structure de ce que vous devez obtenir :
air_quality[c(30, 48, 75, 110, 153), ]
## Ozone Solar.R Wind Temp Month Day Month.Name Date
## 30 115 223 5.7 79 5 30 May 1973-05-30
## 48 37 284 20.7 72 6 17 June 1973-06-17
## 75 NA 291 14.9 91 7 14 July 1973-07-14
## 110 23 115 7.4 76 8 18 August 1973-08-18
## 153 20 223 11.5 68 9 30 September 1973-09-30
str(air_quality)
## 'data.frame': 153 obs. of 8 variables:
## $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ...
## $ Solar.R : int 190 118 149 313 NA NA 299 99 19 194 ...
## $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
## $ Temp : int 67 72 74 62 56 66 65 59 61 69 ...
## $ Month : int 5 5 5 5 5 5 5 5 5 5 ...
## $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Month.Name: chr "May" "May" "May" "May" ...
## $ Date : Date, format: "1973-05-01" "1973-05-02" "1973-05-03" ...
Ajoutez à votre copie de airquality créée à la question
1 une autre variable contenant les observations catégorisées de la
variable Wind :
Wind inférieure ou égale à 6, la
catégorie associée doit être "light";Wind supérieure à 6, mais inférieure
ou égale à 12, la catégorie associée doit être
"moderate";Wind supérieure à 12, mais
inférieure ou égale à 18, la catégorie associée doit être
"strong";Voici un extrait et la structure de ce que vous devez obtenir :
air_quality[c(30, 48, 75, 110, 153), ]
## Ozone Solar.R Wind Temp Month Day Month.Name Date Wind.Catego
## 30 115 223 5.7 79 5 30 May 1973-05-30 light
## 48 37 284 20.7 72 6 17 June 1973-06-17 <NA>
## 75 NA 291 14.9 91 7 14 July 1973-07-14 strong
## 110 23 115 7.4 76 8 18 August 1973-08-18 moderate
## 153 20 223 11.5 68 9 30 September 1973-09-30 moderate
str(air_quality)
## 'data.frame': 153 obs. of 9 variables:
## $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ...
## $ Solar.R : int 190 118 149 313 NA NA 299 99 19 194 ...
## $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
## $ Temp : int 67 72 74 62 56 66 65 59 61 69 ...
## $ Month : int 5 5 5 5 5 5 5 5 5 5 ...
## $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Month.Name : chr "May" "May" "May" "May" ...
## $ Date : Date, format: "1973-05-01" "1973-05-02" "1973-05-03" ...
## $ Wind.Catego: Factor w/ 3 levels "light","moderate",..: 2 2 3 2 3 3 2 3 NA 2 ...
# ---- Solution avec cut ----
air_quality$Wind.Catego <-
cut(
x = air_quality$Wind,
breaks = c(-Inf, 6, 12, 18, Inf),
labels = c("light", "moderate", "strong", "extreme"),
right = TRUE
)
# Pourquoi ne pas avoir mis NA comme dernière modalité ?
# Parce que NA serait alors compris comme une modalité de la variable,
# et non comme une donnée manquante.
# Mais il faut maintenant remplacer les valeurs égales à la dernière
# modalité par NA.
air_quality$Wind.Catego[air_quality$Wind.Catego == "extreme"] <- NA
# Et il faut laisser tomber le niveau "extreme".
air_quality$Wind.Catego <- droplevels(air_quality$Wind.Catego)
# ---- Solution avec ifelse ----
air_quality$Wind.Catego2 <- ifelse(
test = air_quality$Wind <= 6,
yes = "light",
no = ifelse(
test = air_quality$Wind > 6 & air_quality$Wind <= 12,
yes = "moderate",
no = ifelse(
test = air_quality$Wind > 12 & air_quality$Wind <= 18,
yes = "strong",
no = NA
)
)
)
# Si nous voulons un facteur, comme ce que retourne la fonction cut :
air_quality$Wind.Catego2 <- as.factor(air_quality$Wind.Catego)
# ---- Solution avec [ et <- ----
# Initialisation d'une variable vide
air_quality$Wind.Catego3 <- vector(
mode = "character",
length = nrow(air_quality)
)
# Ensuite correctement remplie
air_quality$Wind.Catego3[air_quality$Wind <= 6] <- "light"
air_quality$Wind.Catego3[air_quality$Wind > 6 & air_quality$Wind <= 12] <- "moderate"
air_quality$Wind.Catego3[air_quality$Wind > 12 & air_quality$Wind <= 18] <- "strong"
air_quality$Wind.Catego3[air_quality$Wind > 18] <- NA
# Si nous voulons un facteur, comme ce que retourne la fonction cut :
air_quality$Wind.Catego3 <- as.factor(air_quality$Wind.Catego)
# ---- Solution avec le tidyverse ----
air_quality <- mutate(
air_quality,
Wind.Catego4 = factor( # pour avoir un facteur, comme avec cut
case_when(
Wind <= 6 ~ "light",
Wind > 6 & Wind <= 12 ~ "moderate",
Wind > 12 & Wind <= 18 ~ "strong",
Wind > 18 ~ NA_character_ # Seulement NA ne fonctionne pas
)
)
)
# Référence : https://dplyr.tidyverse.org/reference/case_when.html
# La fiche d'aide suivante mentionne l'existence de versions de NA possédant
# un type spécifique : NA_integer_, NA_real_, NA_complex_ et NA_character_
help(NA)
# ---- Comparaison des solutions ----
# Est-ce que les 4 solutions donnent vraiment le même résultat ?
identical(air_quality$Wind.Catego, air_quality$Wind.Catego2)
# [1] TRUE
identical(air_quality$Wind.Catego, air_quality$Wind.Catego3)
# [1] TRUE
identical(air_quality$Wind.Catego, air_quality$Wind.Catego4)
# [1] TRUE
# Oui. Retirons donc les variables en double.
air_quality$Wind.Catego2 <- NULL
air_quality$Wind.Catego3 <- NULL
air_quality$Wind.Catego4 <- NULLRetour sur la question 2 de la semaine dernière
Les données airquality comprennent des données
manquantes. Si nous voulions traiter ces données, il faudrait décider
quoi faire avec les données manquantes. La semaine dernière, nous avons
fait l’exercice de les omettre. Une autre option pour traiter ces
données serait de les remplacer par des valeurs imputées.
Nous pourrions remplacer les données manquantes par la valeur moyenne de la variable en question pour le mois correspondant. Ce type d’imputation par une valeur moyenne est rarement la meilleure façon de faire, d’un point de vue théorique. C’est cependant un bon exercice pour nous.
Procédez donc à ce remplacement, dans la copie du jeu de données créée à la question 1.
Par exemple, la valeur moyenne d’Ozone au mois de mai,
en omettant les données manquantes, est 23.6153846. Ainsi, les données
manquantes dans la colonne 1 aux lignes 5, 10, 25, 26 et 27 devraient
être remplacées par 23.6153846.
Contrainte : NE PAS UTILISER DE BOUCLE.
# Calcul des moyennes par mois
mean_per_month <- aggregate(
x = airquality[, c("Ozone", "Solar.R")],
by = list(Month = airquality$Month),
FUN = mean, na.rm = TRUE
)
# Fusion par association avec airquality
air_qualityTemp <- merge(x = air_quality, y = mean_per_month, by = "Month")
# Imputation
air_quality$Ozone <- ifelse(
test = is.na(air_qualityTemp$Ozone.x),
yes = air_qualityTemp$Ozone.y,
no = air_qualityTemp$Ozone.x
)
air_quality$Solar.R <- ifelse(
test = is.na(air_qualityTemp$Solar.R.x),
yes = air_qualityTemp$Solar.R.y,
no = air_qualityTemp$Solar.R.x
)
View(air_quality)
# ##############
# AUTRE SOLUTION
# mais nécessitant la création d'une fonction,
# ce que nous n'avons pas encore appris à faire.
ozone_mean <- ave(
airquality$Ozone,
airquality$Month,
FUN = function(x) mean(x, na.rm = TRUE)
)
# La commande suivante retourne uniquement des NA
# ozone_mean <- ave(airquality$Ozone, airquality$Month, FUN = mean, na.rm = TRUE)
# parce que l'argument na.rm = TRUE est ignoré. Contrairement aux fonctions
# de la famille des apply, l'argument ... de ave sert à recevoir en entrée
# un nombre indéterminé d'arguments, et non à passer des arguments à la
# sous-fonction FUN.
solar_mean <- ave(
airquality$Solar.R,
airquality$Month,
FUN = function(x) mean(x, na.rm = TRUE)
)
# Imputation
air_quality$Ozone <- ifelse(
test = is.na(air_quality$Ozone),
yes = ozone_mean,
no = air_quality$Ozone
)
air_quality$Solar.R <- ifelse(
test = is.na(air_quality$Solar.R),
yes = solar_mean,
no = air_quality$Solar.R
)
View(air_quality)Créez un nouveau jeu de données contenant l’extrait suivant de
airquality :
Ozone, Solar.R,
Wind et Temp seulement.Vous devez effectuer cette tâche de 2 façons :
dplyr.Comparez les résultats obtenus avec les deux approches.
# R de base : utilisons la fonction subset
extrait <- subset(
airquality,
subset = Month %in% c(6, 7, 8),
select = Ozone:Temp
)
# Remarque : Ozone:Temp est compris comme toutes les variables se situant
# entre les variables Ozone et Temp inclusivement -> équivalent à
# c(Ozone, Solar.R, Wind, Temp) étant donné l'ordre des variables.
# Même sélection avec l'opérateur [
extrait <- airquality[
airquality$Month %in% c(6, 7, 8),
c("Ozone", "Solar.R", "Wind", "Temp")
]
# L'opérateur crochet ne comprend pas les raccourcis avec l'opérateur :
# pour identifier une série de variables consécutives.
# Avec dplyr
extrait_autre <- select(filter(airquality, Month %in% c(6, 7, 8)), Ozone:Temp)
# Comparaison
all.equal(extrait, extrait_autre)
# [1] "Attributes: < Component “row.names”: Mean relative difference: 0.4 >"
# Seuls les noms de lignes diffèrent. [ et subset conservent les noms de
# lignes originaux tandis que filter de dplyr renomme les lignes.Reprenez l’extrait du jeu de données airquality créé à
la question précédente. Normalisez les valeurs de ces variables en les
ramenant toutes sur une échelle entre 0 et 1.
# Obtention des minimums par variable
minimums <- apply(extrait, MARGIN = 2, FUN = min, na.rm = TRUE)
# Obtention des maximums par variable
maximums <- apply(extrait, MARGIN = 2, FUN = max, na.rm = TRUE)
# Normalisation
extrait_01norm <- scale(extrait, center = minimums, scale = maximums - minimums)
# Vérification
summary(extrait_01norm)
## Ozone Solar.R Wind Temp
## Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.1242 1st Qu.:0.3938 1st Qu.:0.2737 1st Qu.:0.4062
## Median :0.2609 Median :0.6400 Median :0.3947 Median :0.5312
## Mean :0.2987 Mean :0.5741 Mean :0.4013 Mean :0.5425
## 3rd Qu.:0.4410 3rd Qu.:0.7785 3rd Qu.:0.5158 3rd Qu.:0.6562
## Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000
## NA's :31 NA's :3 Reprenons encore une fois les données sur la production de fruits
dans le monde enregistrées dans le fichier fruitsFinal.rds.
Ce fichier est téléchargeable à partir du site web du cours dans le
contenu de cette semaine.
Les variables de ces données sont ainsi définies :
Region : Région du monde, presque toujours un pays,
mais parfois un territoire rattaché à un pays;Item : Nom du ou des fruits, ou du groupe de
fruits;Annee : Année (2014, 2015 ou 2016);Production : Quantité de fruits produits, en
tonnes;Superficie : Superficie de la région, en
km2.Téléchargez le fichier fruitsFinal.rds et chargez en R
l’objet qu’il contient. Nommez cet objet fruits.
fruits <- readRDS("C:/coursR/fruitsFinal.rds")
str(fruits)
## 'data.frame': 7758 obs. of 5 variables:
## $ Region : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
## $ Item : chr "Fruits, agrumes nda" "Fruits, agrumes nda" "Figues" "Figues" ...
## $ Annee : int 2016 2015 2014 2015 2015 2014 2015 2014 2016 2014 ...
## $ Production: int 17472 3043 6100 4996 50657 3000 87686 46186 17894 23561 ...
## $ Superficie: num 652230 652230 652230 652230 652230 ...
Quels noms de régions dans ces données contiennent le mot
"Republique" ?
regions_uniques <- unique(fruits$Region)
grep(pattern = "Republique", x = regions_uniques, value = TRUE)
## [1] "l'ex-Republique yougoslave de Macedoine" "Republique arabe syrienne"
## [3] "Republique centrafricaine" "Republique de Coree"
## [5] "Republique de Moldova" "Republique democratique du Congo"
## [7] "Republique democratique populaire lao" "Republique dominicaine"
## [9] "Republique populaire democratique de Coree" "Republique-Unie de Tanzanie" Si des noms de régions comportent un bout entre parenthèses, retirez ce bout.
# Couper à la parenthèse ouvrante
etape_1 <- strsplit(x = fruits$Region, split = "(", fixed = TRUE)
# Est-ce que des noms comportent plus d'une parenthèse ouvrante?
table(sapply(etape_1, FUN = length))
## 1 2
## 7500 258
# Non, car le résultat de la commande strsplit serait alors de longueur 3 ou plus
# Est-ce que des noms comportent d'autres mots après la parenthèse fermante?
verif <- strsplit(x = fruits$Region, split = ")", fixed = TRUE)
table(sapply(verif, FUN = length))
## 1
## 7758
# Non, parce que le résultat de la dernière commande strsplit serait
# alors de longueur 2 ou plus
# Pour retirer les bouts entre parenthèses, il suffit donc de conserver seulement
# le premier élément de chaque vecteur dans la liste etape_1
fruits$Region <- sapply(etape_1, FUN = "[", i = 1)
# ou
fruits$Region <- sapply(etape_1, FUN = head, n = 1)Si des noms d’items comportent le caractère "/",
remplacez toutes ses occurrences par la chaîne de caractères
" ou ".
# Un nom d'item comporte le caractère `"/"`.
unique(fruits$Item)
## [1] "Fruits, agrumes nda" "Figues"
## [3] "Fruit a noyau, nda" "Abricots"
## [5] "Baies nda" "Raisins"
## [7] "Oranges" "Fruits frais nda"
## [9] "Pasteques" "Melons, cantaloups"
## [11] "Peches et nectarines" "Poires"
## [13] "Pommes" "Prunes et prunelles"
## [15] "Bananes" "Pamplemousses et pomelos"
## [17] "Papayes" "Ananas"
## [19] "Avocats" "Citrons et limes"
## [21] "Cerises" "Coings"
## [23] "Fraises" "Mangues, mangoustans et goyaves"
## [25] "Tangerines, mandarines, clementines, satsumas" "Dattes"
## [27] "Grillottes" "Caroubes"
## [29] "Fruits tropicaux frais, nda" "Groseilles a maquereaux"
## [31] "Cassis et groseilles" "Framboises"
## [33] "Myrtilles" "Kiwis"
## [35] "Plaqueminiers/kakis" "Canneberges"
## [37] "Plantains et autres" "Pomme d'acajou"
## [39] "Fruit a pepins, nda"
# Il s'agit de "Plaqueminiers/kakis"
# Remplacement du caractère
fruits$Item <- gsub(
pattern = "/",
replacement = " ou ",
x = fruits$Item, fixed = TRUE
)
# Vérification
unique(fruits$Item)
## ... lignes inchangées
## [35] "Plaqueminiers ou kakis" "Canneberges"
## ... lignes inchangéesOrdonnez les observations du data frame fruits en ordre
ascendant d’identifiant des fruits (variable Item), puis en
ordre ascendant du nom de la région pour un même fruit et finalement en
ordre décroissant d’année par combinaison fruit-région.
Vous devez effectuer cette tâche de 2 façons :
order,arrange du package
dplyr.Comparez les résultats obtenus avec les deux approches.
ordre <- order(fruits$Item, fruits$Region, -fruits$Annee)
fruits_order <- fruits[ordre,]
View(fruits_order)
fruits_arrange <- arrange(fruits, Item, Region, desc(Annee))
View(fruits_arrange)
all.equal(fruits_order, fruits_arrange)
## [1] "Attributes: < Component “row.names”: Mean relative difference: 0.6586219 >"
# Seuls les noms des lignes diffèrent.
# Encore une fois, l'approche avec le R de base a conservé les
# noms de lignes originaux, alors que dplyr a renommé les lignes.Le jeu de données fruits a une mise en forme longue.
Créez un autre jeu de données contenant les mêmes données, mais sous une
mise en forme large, avec les valeurs de production de fruits pour les
différentes années dans des colonnes distinctes.
Vous devez effectuer cette tâche de 2 façons :
reshape,pivot_wider du package
tidyr.Comparez les résultats obtenus avec les deux approches.
# Avec reshape
fruits_large <- reshape(
data = fruits,
direction = "wide",
v.names = "Production",
timevar = "Annee",
idvar = c("Region", "Item")
)
str(fruits_large)
## 'data.frame': 2602 obs. of 6 variables:
## $ Region : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
## $ Item : chr "Fruits, agrumes nda" "Figues" "Fruit a noyau, nda" "Abricots" ...
## $ Superficie : num 652230 652230 652230 652230 652230 ...
## $ Production.2016: num 17472 3143 51304 17894 23979 ...
## $ Production.2015: num 3043 4996 50657 87686 24357 ...
## $ Production.2014: num 3000 6100 46186 90000 23561 ...
## - attr(*, "reshapeWide")=List of 5
## ..$ v.names: chr "Production"
## ..$ timevar: chr "Annee"
## ..$ idvar : chr "Region" "Item"
## ..$ times : int 2016 2015 2014
## ..$ varying: chr [1, 1:3] "Production.2016" "Production.2015" "Production.2014"
View(fruits_large)
# Avec pivot_wider
fruits_large_autre <- pivot_wider(
data = fruits,
names_from = Annee,
names_prefix = "Production.", # pas obligatoire, seulement pour imiter reshape
values_from = Production
)
str(fruits_large_autre)
## Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2602 obs. of 6 variables:
## $ Region : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
## $ Item : chr "Fruits, agrumes nda" "Figues" "Fruit a noyau, nda" "Abricots" ...
## $ Superficie: num 652230 652230 652230 652230 652230 ...
## $ Production.2016: num 17472 3143 51304 17894 23979 ...
## $ Production.2015: num 3043 4996 50657 87686 24357 ...
## $ Production.2014: num 3000 6100 46186 90000 23561 ...
View(fruits_large_autre)
# À part
# - les attributs ajoutés par reshape
# - la classe du résultat retourné par pivot_wider (un tibble),
# - les noms de lignes
# est-ce que les deux jeux de données sont équivalents?
attr(fruits_large, "reshapeWide") <- NULL
fruits_large_autre <- as.data.frame(fruits_large_autre)
row.names(fruits_large) <- NULL
row.names(fruits_large_autre) <- NULL
all.equal(fruits_large, fruits_large_autre)
## [1] TRUE
# Réponse : oui!Calculez en R dans combien de jours est le lundi de la semaine de
lecture (7 mars 2022) en utilisant le format Date.
WorldPhonesLes deux prochaines questions utilisent la matrice
WorldPhones, incluse dans le package datasets
de l’installation de base de R. Il s’agit d’observations de nombres de
téléphones (en milliers) dans différentes régions du monde au cours des
années 1951, 1956, 1957, 1958, 1959, 1960 et 1961.
WorldPhones
## N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer
## 1951 45939 21574 2876 1815 1646 89 555
## 1956 60423 29990 4708 2568 2366 1411 733
## 1957 64721 32510 5230 2695 2526 1546 773
## 1958 68484 35218 6662 2845 2691 1663 836
## 1959 71799 37598 6856 3000 2868 1769 911
## 1960 76036 40341 8220 3145 3054 1905 1008
## 1961 79831 43173 9053 3338 3224 2005 1076
Le jeu de données WorldPhones a une mise en forme large.
Transformez-le dans une mise en forme longue, avec les nombres de
téléphones dans une seule colonne et l’identification de la région dans
une autre. Pour ce faire, vous devez préalablement transformer la
matrice en data frame et y ajouter une colonne contenant les années, qui
sont à l’origine stockées dans les noms des lignes.
Vous devez effectuer la tâche de modification de mise en forme de 2 façons :
reshape,pivot_longer du package
tidyr.Comparez les résultats obtenus avec les deux approches.
# Transformation en data frame avec une nouvelle colonne pour l'année
phones <- data.frame(WorldPhones)
phones$Year <- as.numeric(rownames(phones))
# Avec reshape
phones_long <- reshape(
data = phones,
direction = "long",
varying = c("N.Amer", "Europe", "Asia", "S.Amer", "Oceania", "Africa", "Mid.Amer"),
v.names = "Nbr.Phones",
timevar = "Region",
times = c("N.Amer", "Europe", "Asia", "S.Amer", "Oceania", "Africa", "Mid.Amer"),
idvar = "Year"
)
str(phones_long)
## 'data.frame': 49 obs. of 3 variables:
## $ Year : num 1951 1956 1957 1958 1959 ...
## $ Region : chr "N.Amer" "N.Amer" "N.Amer" "N.Amer" ...
## $ Nbr.Phones: num 45939 60423 64721 68484 71799 ...
## - attr(*, "reshapeLong")=List of 4
## ..$ varying:List of 1
## .. ..$ Nbr.Phones: chr "N.Amer" "Europe" "Asia" "S.Amer" ...
## .. ..- attr(*, "v.names")= chr "Nbr.Phones"
## .. ..- attr(*, "times")= chr "N.Amer" "Europe" "Asia" "S.Amer" ...
## ..$ v.names: chr "Nbr.Phones"
## ..$ idvar : chr "Year"
## ..$ timevar: chr "Region"
View(phones_long)
# Avec pivot_longer
phones_long_autre <- pivot_longer(
data = phones,
cols = c(N.Amer, Europe, Asia, S.Amer, Oceania, Africa, Mid.Amer),
names_to = "Region",
values_to = "Nbr.Phones"
)
str(phones_long_autre)
## Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 49 obs. of 3 variables:
## $ Year : num 1951 1951 1951 1951 1951 ...
## $ Region : chr "N.Amer" "Europe" "Asia" "S.Amer" ...
## $ Nbr.Phones: num 45939 21574 2876 1815 1646 ...
View(phones_long_autre)
# Différences entre les deux résultats :
# - les attributs ajoutés par reshape
# - la classe du résultat retourné par pivot_wider (un tibble),
# - les noms de lignes
# - l'odre des observations
attr(phones_long, "reshapeLong") <- NULL
phones_long_autre <- as.data.frame(phones_long_autre)
row.names(phones_long) <- NULL
row.names(phones_long_autre) <- NULL
phones_long <- dplyr::arrange(phones_long, Region, Year)
phones_long_autre <- dplyr::arrange(phones_long_autre, Region, Year)
all.equal(phones_long, phones_long_autre)
## [1] TRUESoumettez le code suivant pour créer un petit jeu de données
contenant la population, en milliers, pour les mêmes régions du monde
que celles présentes dans le jeu de données WorldPhones,
mais pour l’année 1960 seulement. (Ces données sont tirées du site web
suivant : https://en.wikipedia.org/wiki/List_of_continents_by_population)
population_1960 <- data.frame(
An = 1960,
Territoire = c("N.Amer", "Mid.Amer", "S.Amer",
"Europe", "Africa", "Asia", "Oceania"),
Pop = c(204167, 72124, 149066, 605619, 284887, 1686698, 15784),
stringsAsFactors = FALSE
)
Effectuez une fusion par association entre le jeu de donnée créé à la
question précédente et le jeu de données population_1960 en
faisant correspondre les régions et les années. Ne conservez que les
combinaisons présentes dans les deux jeux de données. En bout de ligne,
vous devriez un jeu de données similaire au suivant.
## Region Year Nbr.Phones Pop
## 1 N.Amer 1960 76036 204167
## 2 Europe 1960 40341 605619
## 3 Asia 1960 8220 1686698
## 4 S.Amer 1960 3145 149066
## 5 Oceania 1960 3054 15784
## 6 Africa 1960 1905 284887
## 7 Mid.Amer 1960 1008 72124
Vous devez effectuer cette tâche de 2 façons :
dplyr.Comparez les résultats obtenus avec les deux approches.
# Fonction merge du package base de R
phone1960 <- merge(
x = phones_long,
y = population_1960,
by.x = c("Region", "Year"),
by.y = c("Territoire", "An"),
sort = FALSE
)
phone1960
## Region Year Nbr.Phones Pop
## 1 N.Amer 1960 76036 204167
## 2 Europe 1960 40341 605619
## 3 Asia 1960 8220 1686698
## 4 S.Amer 1960 3145 149066
## 5 Oceania 1960 3054 15784
## 6 Africa 1960 1905 284887
## 7 Mid.Amer 1960 1008 72124
# Fonction inner_join du package dplyr
phone1960_autre <- inner_join(
x = phones_long,
y = population_1960,
by = c("Region" = "Territoire", "Year" = "An")
)
phone1960_autre
## Year Region Nbr.Phones Pop
## 1 1960 N.Amer 76036 204167
## 2 1960 Europe 40341 605619
## 3 1960 Asia 8220 1686698
## 4 1960 S.Amer 3145 149066
## 5 1960 Oceania 3054 15784
## 6 1960 Africa 1905 284887
## 7 1960 Mid.Amer 1008 72124
# Seule différence entre les deux résultats :
# - deux premières colonnes pas dans le même ordre.
phone1960_autre <- phone1960_autre[, names(phone1960)]
all.equal(phone1960, phone1960_autre)
## [1] TRUEdata.tableCréez un data table contenant les données du data frame
fruits. Avec les fonctionnalités du package
data.table, apportez les modifications suivantes à cet
objet :
Superficie_mi2 contenant
les superficies en miles carrés plutôt que kilomètres carrés (facteur de
conversion = 0.386102);Production.library(data.table)
fruits_dt <- as.data.table(fruits)
str(fruits_dt)
# Sélection d'observations : même syntaxe que le R de base
fruits_dt <- fruits_dt[Annee == 2014, ]
str(fruits_dt)
# Ajout de variable : fait en référence (aucune assignation nécessaire)
fruits_dt[, Superficie_mi2 := Superficie * 0.386102]
str(fruits_dt)
# Modification de l'ordre des observations : aussi fait en référence
setorder(fruits_dt, -Production, na.last = TRUE)
str(fruits_dt)
# Remarque : La fonction order a aussi un argument na.last, mais sa valeur
# par défaut est TRUE, alors qu'elle est FALSE pour setorder.