Objets (R Objects)

Les objets dans R

R utilise des objets pour stocker de l'information. Voici un objet simple qui ne stocke que la valeur numérique 1 :

my_number <- 1

Nous avons créé un objet nommé my_number et lui avons affecté la valeur 1. L'affectation de la valeur 1 a été réalisée avec les symboles <-, appelés the assignment operator, soit opérateur d'affectation en français. On dit que my_number reçoit la valeur 1. L'objet my_number contient désormais une information sous la forme d'une valeur numérique. Demandons à R de quel type d'objet il s'agit :

class(my_number)
[1] "numeric"

D'après ce qui précède, R interprète my_number comme un objet numérique, ce qui semble raisonnable. Faisons la même opération avec une chaîne de caractères :

my_string <- "Hej! Mitt namn är Salvador."
class(my_string)
[1] "character"

L'objet my_string est un objet character, ce qui signifie qu'il est composé de caractères et de symboles. Ces deux exemples montrent qu'au moment même où nous créons un objet, R tente de deviner le type d'information qu'il contient. Voyons comment R interprète une valeur numérique entourée de guillemets :

my_object <- "1"
class(my_object)
[1] "character"

R interprète my_object comme une chaîne de caractères (objet character), ce qui s'explique par le fait que le chiffre 1 était entouré de guillemets : R suppose alors que nous voulons stocker une chaîne de caractères.

Toute information que vous stockez dans votre Environment est un objet. Voici quelques exemples d'objets :

  • Les tableaux (dataframes) sont des objets.
  • Les valeurs individuelles enregistrées (comme my_object ci-dessus) sont des objets.
  • Les résultats de modèles de régression sont des objets.

En principe, tout ce que vous créez dans R est un objet. Nous allons passer en revue ci-dessous les différents types d'objets dans R.

4.1 Atomic Vectors (vecteurs atomiques)

Le type d'objet le plus simple dans R est l'atomic vector (vecteur atomique). Les atomic vectors sont utilisés en permanence lorsque vous travaillez dans R. Créons un vecteur atomique à l'aide de la fonction [c()](https://rdrr.io/r/base/c.html). Cette fonction combine plusieurs éléments pour former un vecteur. Nous nommons l'objet my_first_vector et il contiendra six valeurs numériques :

my_first_vector <- c(1, 2, 3, 4, 5, 6)

Nous pouvons vérifier si R considère my_first_vector comme un atomic vector à l'aide de la fonction [is.vector()](https://rdrr.io/r/base/vector.html) :

## is.vector() vérifie si un objet est un atomic vector
is.vector(my_first_vector)
[1] TRUE

La fonction [is.vector()](https://rdrr.io/r/base/vector.html) a renvoyé la valeur TRUE, ce qui signifie que my_first_vector est un atomic vector. Comme my_first_vector ne contient que des valeurs numériques, R le considère comme un vecteur numérique, ce que l'on peut vérifier avec la fonction [is.numeric()](https://rdrr.io/r/base/numeric.html) :

## is.numeric() vérifie si un atomic vector est numérique
is.numeric(my_first_vector)
[1] TRUE

Les atomic vectors n'ont qu'une seule dimension. Chaque vecteur ne peut stocker qu'un seul type de données. Pour gérer tous les types de données, il existe donc six types fondamentaux d'atomic vectors :

  • double : valeurs numériques avec ou sans décimales
  • integer : nombres entiers (sans décimales)
  • character : caractères, symboles, texte
  • logical : OUI/NON, 0/1, TRUE/FALSE
    • Synonymes : valeurs logiques (fr), boolean (angl.), valeurs booléennes (fr).
  • Les vecteurs complex et raw existent, mais ne sont pratiquement jamais utilisés.
my_doubles <- c(1.2, 2.4, 32.1)

my_integers <- c(1L, 2L, 3L)

my_characters <- c("A", "B", "Hello", "My phone is dead")

my_logicals <- c(TRUE, TRUE, FALSE, TRUE, FALSE)

Vous pouvez vérifier si un vecteur appartient à l'un de ces types à l'aide des fonctions [is.double()](https://rdrr.io/r/base/double.html), [is.numereric()](https://rdrr.io/r/base/numeric.html), [is.character()](https://rdrr.io/r/base/character.html), [is.logical()](https://rdrr.io/r/base/logical.html). Ces fonctions renvoient la valeur TRUE ou FALSE.

Si vous devez vérifier de quel type de vecteur il s'agit, vous pouvez utiliser la fonction [typeof()](https://rdrr.io/r/base/typeof.html). Ci-dessous, nous créons un vecteur numérique avec des décimales, puis nous demandons quelle est sa classe et quel est son type.

my_doubles <- c(1.2, 2.4, 32.1)
class(my_doubles)
[1] "numeric"
typeof(my_doubles)
[1] "double"

4.1.0.1 Longueur des vecteurs

La longueur d'un vecteur est tout simplement le nombre d'éléments qu'il contient. Créons un vecteur atomique de 5 valeurs numériques et vérifions sa longueur :

my_values <- c(1, 2, 3, 4, 5)
length(my_values)
[1] 5

Créons un vecteur contenant une longue chaîne pour en vérifier la longueur :

my_string <- c("Det är roligt att lära sig R!")
length(my_string)
[1] 1

La longueur de ce vecteur était de 1, car il contient 1 élément, à savoir la phrase « Det är roligt att lära sig R! ». Créons un vecteur contenant deux chaînes de caractères :

my_string <- c("Det är roligt att lära sig R!", "Det kommer ta en vecka att lära sig R")
length(my_string)
[1] 2

my_string contient désormais 2 chaînes de caractères, et le vecteur a donc une longueur de 2.

Un atomic vector ne peut stocker qu'un seul type de données. Vérifions-le en créant un vecteur contenant à la fois des valeurs numériques, des chaînes de caractères et des valeurs logiques.

## Créer un vecteur contenant des chaînes de caractères, des valeurs numériques et des valeurs booléennes
mixed <- c("Det är roligt att lära sig R!", 1, 2, TRUE, FALSE)

Affichons le résultat :

mixed
[1] "Det är roligt att lära sig R!" "1"
[3] "2"                             "TRUE"
[5] "FALSE"

Vérifions la classe du vecteur :

## Vérifier la classe du vecteur
class(mixed)
[1] "character"

Notez les points suivants :

  1. Tous les éléments ont été affichés entre guillemets, ce qui signifie que R a converti tous les éléments en chaînes de caractères, y compris les chiffres, TRUE et FALSE. C'est ce qu'on appelle la coercion (conversion forcée) : un type de données a été converti automatiquement en un autre. Le chiffre 1 n'est donc plus une valeur numérique ; il ne représente plus que le caractère 1. TRUE et FALSE ne sont plus des valeurs booléennes ; ce ne sont plus que les mots TRUE et FALSE.
  2. Cela explique pourquoi la fonction [class()](https://rdrr.io/r/base/class.html) indique que le vecteur est de type character.
  3. Le type étant désormais character, vous ne pouvez plus effectuer de calculs mathématiques (par exemple calculer une moyenne) sur ce vecteur.

Vous devez être explicite lorsque vous créez des vecteurs dans R. Les chiffres de 1 à 4 peuvent être créés aussi bien sous forme de vecteur numérique que de vecteur character. Pour créer un vecteur character, chaque élément doit être indiqué entre guillemets :

Exemple 1 : créer un vecteur numérique

my_numbers <- c(1, 2, 3, 4)
my_numbers
[1] 1 2 3 4

Exemple 2 : créer un vecteur character

my_characters <- c("1", "2", "3", "4")
my_characters
[1] "1" "2" "3" "4"

Vous pouvez convertir des vecteurs d'un type à l'autre avec les fonctions [as.character()](https://rdrr.io/r/base/character.html), [as.numeric()](https://rdrr.io/r/base/numeric.html), etc.

Exemple 3 : convertir un vecteur numérique en character

## Crée un vecteur numérique
my_numbers <- c(1, 2, 3, 4)

## Convertit le vecteur numérique en character

my_characters <- as.character(my_numbers)
## Affiche le résultat
my_characters
[1] "1" "2" "3" "4"

Vous pouvez donc convertir un vecteur d'un type à l'autre. Essayons l'inverse, c'est-à-dire passer de caractères à numérique : Exemple 4 : convertir des caractères en numérique

my_characters <- c("1", "2", "3", "4")
my_numbers <- as.numeric(my_characters)

## Print it
my_numbers
[1] 1 2 3 4

Cela a fonctionné, car les chiffres se présentaient dans le bon ordre, sans guillemets. S'il s'agit désormais réellement de valeurs numériques, nous devrions pouvoir en calculer la moyenne :

mean(my_numbers)
[1] 2.5

Nous sommes maintenant certains que le résultat est correct. Notez que les conversions peuvent parfois donner des résultats inattendus. Il est donc important d'effectuer une forme de contrôle pour s'assurer que la conversion se déroule comme prévu.

Essayons de convertir la chaîne « Hej » en valeur numérique :

## Créer un vecteur character
my_characters <- c("Hej")

## Le convertir en vecteur numérique
my_numbers <- as.numeric(my_characters)
Warning: NAs introduced by coercion
## Afficher le résultat
my_numbers
[1] NA

Nous avons obtenu ici l'avertissement « NAs introduced by coercion ». NA signifie « Not Available » ou « Not Applicable » selon le contexte. Dans le cas présent, il s'agit de Not Available, ce qui signifie que la valeur est manquante. La conversion a donc conduit R à forcer la valeur en NA. Lorsque nous affichons l'objet my_numbers, il ne contient qu'une seule valeur, et c'est NA. Autrement dit, R ne peut pas convertir « Hej » en valeur numérique.

4.1.1 Double vector

Un double stocke des valeurs numériques. Les valeurs peuvent comporter des décimales. R enregistre pratiquement toujours les vecteurs numériques en tant que double, même s'ils n'ont pas de décimales. Vérifions-le dès maintenant :

## Créer un vecteur numérique sans décimales
my_numbers <- c(1, 2, 3)
## Vérifier s'il s'agit d'un double
is.double(my_numbers)
[1] TRUE
## Créer un vecteur numérique avec décimales
your_numbers <- c(1.1, 2.2, 3.3)

## Vérifier s'il s'agit d'un double
is.double(your_numbers)
[1] TRUE

Même si l'objet my_numbers n'est composé que de nombres entiers, R l'enregistre en tant que double. Nous pouvons vérifier que le vecteur n'est pas un entier :

is.integer(my_numbers)
[1] FALSE

4.1.2 Integer vector (entiers)

Un integer vector ne stocke que des nombres entiers. Un nombre entier est une valeur numérique sans décimales. Il est peu probable que vous ayez besoin de travailler avec ce type de vecteur, car le vecteur double peut lui aussi gérer les entiers. Vous pouvez en principe toujours utiliser double plutôt qu'integer. Vous aurez très rarement à vous en préoccuper, car R s'en charge automatiquement. Si vous souhaitez malgré tout définir un vecteur comme integer, il suffit d'ajouter la lettre L après les chiffres :

my_integers <- c(1L, 5L, 3L, 10L)
is.integer(my_integers)
[1] TRUE

Vous pouvez également forcer (contraindre) un double en integer :

## Créer un vecteur double
my_doubles <- c(1, 2, 3, 4)

## Vérifier s'il s'agit d'un double
is.double(my_doubles)
[1] TRUE
## Convertir le double en integer et enregistrer le résultat dans un nouvel objet nommé my_integers
my_integers <- as.integer(my_doubles)

## Vérifier si my_integers est un vecteur integer
is.integer(my_integers)
[1] TRUE

Disposer de différents types de vecteurs est très utile. Les différents vecteurs servent à des fins différentes. Les opérations mathématiques ne sont possibles que sur les vecteurs numériques et les logicals. Nous allons le démontrer à l'aide de la fonction [mean()](https://rdrr.io/r/base/mean.html), qui calcule la moyenne arithmétique d'une série de valeurs numériques :

## Crée un double
my_values <- c(5, 10, 15, 20)

## Calcule la moyenne et enregistre le résultat dans un nouvel objet nommé my_mean
my_mean <- mean(my_values)

## Affiche l'objet
my_mean
[1] 12.5

Nous avons mentionné plus haut qu'il est possible d'imbriquer des fonctions dans d'autres fonctions, ce qui peut faire gagner beaucoup de place. Calculons à nouveau la moyenne sans enregistrer de nouveaux objets. Notez que la fonction [c()](https://rdrr.io/r/base/c.html) est imbriquée dans la fonction [mean()](https://rdrr.io/r/base/mean.html).

mean(c(5, 10, 15, 20))
[1] 12.5

4.1.3 Character vector (chaînes de caractères)

Le texte et les symboles sont stockés dans des vecteurs character. La commande suivante enregistre une chaîne de caractères en l'entourant de guillemets :

my_string <- c("Detta är en textsträng. Den kan innehålla symboler (@, *, /) och siffror (1, 2, 3)")
my_string
[1] "Detta är en textsträng. Den kan innehålla symboler (@, *, /) och siffror (1, 2, 3)"

Le vecteur my_string enregistre une chaîne contenant des symboles, des lettres et des chiffres. Voici un vecteur character composé de deux chaînes, dont la seconde contient des chiffres et des symboles :

my_string <- c("Detta är den första strängen", "Detta är den andra strängen")
my_string
[1] "Detta är den första strängen" "Detta är den andra strängen"

Comme indiqué plus haut, des chiffres entourés de guillemets sont interprétés comme des caractères (et non comme des valeurs numériques). C'est ce que montre l'exemple ci-dessous, dans lequel nous utilisons également la fonction [paste()](https://rdrr.io/r/base/paste.html) pour afficher des commentaires dans les résultats :

paste("UTAN CITATTECKEN:")
[1] "UTAN CITATTECKEN:"
my_numbers <- c(1, 2, 3)
typeof(my_numbers)
[1] "double"
my_numbers
[1] 1 2 3
paste("MED CITATTECKEN:")
[1] "MED CITATTECKEN:"
your_numbers <- c("1", "2", "3")
typeof(your_numbers)
[1] "character"
your_numbers
[1] "1" "2" "3"

R affiche des guillemets lors de l'affichage de your_numbers pour indiquer clairement que les éléments sont des chaînes de caractères ! Tous les vecteurs character sont affichés entre guillemets dans R.

Une chaîne de caractères contient des caractères et des symboles. Il n'est pas possible d'effectuer des opérations mathématiques sur des chaînes de caractères, même si elles contiennent des chiffres. Voyons deux exemples :

Exemple 1 : créer une chaîne composée de lettres

my_string <- "Detta är en sträng"

## La multiplier par 2
my_string*2
## Error in my_string * 2 : non-numeric argument to binary operator

Exemple 2 : créer une chaîne contenant un nombre

my_string <- "100"

## Multiplier par 2
my_string*2
## Error in my_string * 2 : non-numeric argument to binary operator

Dans les deux exemples, R répond que l'opération ne peut pas être effectuée, car le vecteur n'est pas numérique. Les vecteurs character peuvent donc contenir des chiffres, mais ceux-ci ne sont pas traités comme des valeurs numériques.

Vous devez utiliser des guillemets lorsque vous faites référence aux éléments d'un character vector. Ci-dessous, nous créons deux vecteurs que nous combinons ensuite en un data frame. Nous allons ensuite essayer de filtrer notre data frame pour qu'il ne contienne que des femmes.

## Créer un vecteur contenant le sexe<
sex <- c("Man", "Woman", "Man", "Woman")

## Créer un vecteur contenant des valeurs mesurées de pression artérielle
blood_pressure <- c(140, 130, 120, 150)

## Combiner les vecteurs en un dataframe avec la fonction data.frame()
my_data_frame <- data.frame(sex, blood_pressure)

## Afficher notre data frame
my_data_frame
    sex blood_pressure
1   Man            140
2 Woman            130
3   Man            120
4 Woman            150

Filtrons maintenant pour ne conserver que les femmes. Pour ce faire, nous utilisons la fonction [subset()](https://rdrr.io/r/base/subset.html) :

only_women <- subset(my_data_frame, sex=="Woman")
## Afficher notre data frame
only_women
    sex blood_pressure
2 Woman            130
4 Woman            150

Notez que Woman est indiqué entre guillemets (dans la fonction [subset()](https://rdrr.io/r/base/subset.html)) ci-dessus, ce qui est obligatoire puisque le vecteur est de type character. Si nous voulons filtrer sur la pression artérielle, qui est un double, nous n'utilisons pas de guillemets. Ci-dessous, nous filtrons de façon à ne conserver que les lignes dont la pression artérielle est normale (inférieure ou égale à 130) :

only_normal_blood_pressure <- subset(my_data_frame, blood_pressure <= 130)

## Afficher notre data frame
only_normal_blood_pressure
    sex blood_pressure
2 Woman            130
3   Man            120

4.1.4 Logicals (boolean values, valeurs booléennes)

Certaines variables sont binaires par nature. Lorsque ces variables peuvent être caractérisées par TRUE ou FALSE, on les appelle des logicals. Le fait qu'une personne soit décédée ou vivante peut être considéré comme un logical. Le fait qu'une personne développe un cancer ou non peut également être classé comme TRUE ou FALSE. R peut aussi évaluer des comparaisons et renvoyer TRUE ou FALSE, comme le montre l'exemple ci-dessous :

10>1
[1] TRUE

Il est tout à fait possible d'utiliser les chiffres 1/0 à la place de TRUE/FALSE. Les mots TRUE et FALSE occupent une place particulière dans le langage R. Lorsque ces mots figurent dans des vecteurs, ceux-ci sont automatiquement interprétés comme des logicals. R accepte en outre les abréviations T et F.

## Créer un vecteur de noms
name <- c("Adam", "Umit", "Joanna", "Sarah")

## Créer un vecteur booléen avec TRUE/FALSE selon que la personne est décédée
dead <- c(TRUE, FALSE, TRUE, FALSE)

## Créer un vecteur booléen avec TRUE/FALSE selon que la personne est mariée
married <- c(F, T, F, F)

## Combiner les vecteurs en un data frame
my_data_frame <- data.frame(name, dead, married)

## Afficher notre data frame
my_data_frame
    name  dead married
1   Adam  TRUE   FALSE
2   Umit FALSE    TRUE
3 Joanna  TRUE   FALSE
4  Sarah FALSE   FALSE

Comme on le voit ci-dessus, R accepte les abréviations T pour TRUE et F pour FALSE.

4.1.5 Complex vector, raw vector

Vous n'utiliserez probablement jamais ces vecteurs dans R ; c'est pourquoi nous ne les abordons pas.

4.1.6 Dates, heures et intervalles de temps

Il est très courant de travailler avec des dates, des heures et des intervalles de temps. R, comme plusieurs autres langages, traite les dates et les heures comme des valeurs numériques. Cela signifie qu'à chaque date et à chaque instant est attribuée une valeur numérique qui peut ensuite être utilisée dans les analyses. Pour qu'une valeur numérique puisse être attribuée à une date, il faut une date de référence (une date de départ). Dans le langage SAS, la date de référence est 1960-01-01 00:00:00 GMT. Dans R, la date de référence est 1970-01-01 00:00:00 UTC, mais l'utilisateur peut la modifier. La date de référence utilisée n'a en règle générale aucune importance.

Les dates sont stockées dans des vecteurs de classe POSIXct ou POSIXlt, qui sont en réalité de type double. Un vecteur de type POSIXct ou POSIXt peut ressembler à un vecteur character (car la date peut contenir des « - » ou des « / »), mais il s'agit en fait de valeurs numériques de classe POSIXct ou POSIXlt.

Essayons maintenant de créer des vecteurs composés de dates :

## Créer un vecteur de dates de naissance
birth_date <- c("1990-01-01", "1999-01-04", "2002-05-05", "2001-12-12")

## Créer un vecteur de dates de décès
death_date <- c("2005-02-02", "2009-11-14", "2018-01-01", "2011-11-09")
class(birth_date)
[1] "character"
class(death_date)
[1] "character"

Comme on le voit ci-dessus, aucun des vecteurs n'est de type POSIXct ou POSIXlt (les deux sont de type character), ce qui est attendu puisque nous avons créé les vecteurs en entourant les dates de guillemets. Nous devons indiquer à R que ces vecteurs sont des dates, ce que nous pouvons faire avec les fonctions de l'installation standard de R, ou avec le package lubridate, qui contient des fonctions simples et efficaces pour manipuler les dates. Nous commençons par utiliser les fonctions standard pour convertir les vecteurs en dates.

## Crée des objets date avec GMT (Greenwich Mean Time) comme fuseau horaire
birth_date <- as.POSIXct(birth_date)
death_date <- as.POSIXct(death_date)
class(birth_date)
[1] "POSIXct" "POSIXt"
class(death_date)
[1] "POSIXct" "POSIXt"

R a maintenant converti le vecteur de character en date (POSIXct). Nous allons à présent utiliser la fonction [difftime()](https://rdrr.io/r/base/difftime.html) pour calculer l'écart de temps entre la date de naissance et la date de décès.

difftime(death_date, birth_date)
Time differences in days
[1] 5511.000 3967.000 5720.042 3619.000

Comme on le voit ci-dessus, l'écart de temps a été calculé en jours. Nous pouvons calculer l'écart de temps dans d'autres unités de la façon suivante :

difftime(death_date, birth_date, units="secs")
Time differences in secs
[1] 476150400 342748800 494211600 312681600
difftime(death_date, birth_date, units="mins")
Time differences in mins
[1] 7935840 5712480 8236860 5211360
difftime(death_date, birth_date, units="hours")
Time differences in hours
[1] 132264  95208 137281  86856
difftime(death_date, birth_date, units="weeks")
Time differences in weeks
[1] 787.2857 566.7143 817.1488 517.0000

R utilise également des fuseaux horaires, même si la plupart des utilisateurs n'en tiennent pas compte. Voici quelques exemples de fuseaux horaires :

  • CET : Central European Time.
  • CEST : Central European Summer Time.
  • GMT : Greenwich Mean Time

La gestion des dates, des fuseaux horaires et des intervalles de temps avec les packages standard de R peut être compliquée. C'est pourquoi Garrett Grolemund, Hadley Wickham et Vitalie Spinu ont développé le package lubridate, qui la simplifie considérablement. Commencez par installer lubridate :

install.packages("lubridate")

Chargez ensuite le package :

library(lubridate)
Attaching package: 'lubridate'

The following objects are masked from 'package:base':
    date, intersect, setdiff, union

Lubridate stocke les dates sous la forme du nombre de jours écoulés depuis la date de référence 1970-01-01 00:00:00 GMT. Vous pouvez obtenir la date située 18000 jours après cette date de référence à l'aide de la fonction [as_date()](https://lubridate.tidyverse.org/reference/as_date.html) :

as_date(18000)
[1] "2019-04-14"

Enregistrons quelques dates à l'aide des fonctions de lubridate. Il existe de nombreuses fonctions pour cela. Leur principe est le suivant :

  1. Identifiez dans quel ordre les éléments temporels année (year, y), mois (month, m), jour (day, d), heure (hour, h), minute (minute, m) et secondes (seconds, s) apparaissent dans la date.
  2. Utilisez la fonction qui correspond à l'ordre des éléments temporels.

Le tableau ci-dessous présente quelques exemples de différentes façons d'écrire la date du 31 décembre 2020, ainsi que la fonction de lubridate capable de lire cette date :

Format de date Ordre des éléments temporels Fonction de lubridate
2020-12-31 YYYY-MM-DD ymd()
2020/12/31 YYYY/MM/DD ymd()
20201231 YYYYMMDD ymd()
20-12-31 YY-MM-DD ymd()
201231 YYMMDD ymd()

Exemples de formats de date et fonctions correspondantes de lubridate.

Testons-le en créant un data frame de trois individus, avec leur nom, leur date de naissance, la date du premier examen et la date de décès. Toutes les dates seront écrites de manières différentes afin de tester la fonction [ymd()](https://lubridate.tidyverse.org/reference/ymd.html) :

## Créer les vecteurs
name <- c("David", "Mohammed", "Christina")
birth_date <- ymd("1990-01-01", "1999-01-04", "2002-05-05")
examination_date <- ymd("1990.01.01", "1999.01.04", "2002.05.05")
death_date <- ymd("2005/02/02", "2009/11/14", "2018/01/01")

## Combiner les vecteurs en un data frame (tableau)
my_data <- data.frame(name, birth_date, examination_date, death_date)

## Afficher le data frame
my_data
       name birth_date examination_date death_date
1     David 1990-01-01       1990-01-01 2005-02-02
2  Mohammed 1999-01-04       1999-01-04 2009-11-14
3 Christina 2002-05-05       2002-05-05 2018-01-01

R a donc reconnu les différents formats de date et converti tous les vecteurs en dates. La fonction [sapply()](https://rdrr.io/r/base/lapply.html) permet d'appliquer une fonction à chaque colonne d'un data frame. Nous allons maintenant utiliser [sapply()](https://rdrr.io/r/base/lapply.html) pour vérifier la classe des colonnes de my_data :

## Utiliser sapply() pour appliquer la fonction class() à toutes les colonnes de my_data
sapply(my_data, class)
            name       birth_date examination_date       death_date
     "character"           "Date"           "Date"           "Date"

Modifions l'ordre de l'année, du mois et du jour dans nos dates. Cela ne pose aucun problème tant que nous changeons de fonction lubridate :

## Jour, mois, année
dmy("30-01-2000", "25-12-2001")
[1] "2000-01-30" "2001-12-25"
## Mois, jour, année
mdy("12-25-1999", "09-29-2004")
[1] "1999-12-25" "2004-09-29"
## Année, mois, jour
ymd("20181230", "20191129")
[1] "2018-12-30" "2019-11-29"

Dans l'exemple suivant, nous enregistrons une date qui inclut une heure. Pour la lire correctement, nous ajoutons les lettres h (heure), m (minutes) et s (secondes) de la façon suivante :

ymd_hms("2011-06-04 12:00:00")
[1] "2011-06-04 12:00:00 UTC"

R a attribué à la date le fuseau horaire UTC. R peut gérer environ 600 fuseaux horaires, y compris leurs heures d'été, leurs heures d'hiver et les variations historiques de calendrier. Vous pouvez obtenir la liste de tous les fuseaux horaires en saisissant la commande suivante :

OlsonNames()
  [1] "Africa/Abidjan"                   "Africa/Accra"
  [3] "Africa/Addis_Ababa"               "Africa/Algiers"
  [5] "Africa/Asmara"                    "Africa/Asmera"
  [7] "Africa/Bamako"                    "Africa/Bangui"
  [9] "Africa/Banjul"                    "Africa/Bissau"
 [11] "Africa/Blantyre"                  "Africa/Brazzaville"
 [13] "Africa/Bujumbura"                 "Africa/Cairo"
 [15] "Africa/Casablanca"                "Africa/Ceuta"
 [17] "Africa/Conakry"                   "Africa/Dakar"
 [19] "Africa/Dar_es_Salaam"             "Africa/Djibouti"
 [21] "Africa/Douala"                    "Africa/El_Aaiun"
 [23] "Africa/Freetown"                  "Africa/Gaborone"
 [25] "Africa/Harare"                    "Africa/Johannesburg"
 [27] "Africa/Juba"                      "Africa/Kampala"
 [29] "Africa/Khartoum"                  "Africa/Kigali"
 [31] "Africa/Kinshasa"                  "Africa/Lagos"
 [33] "Africa/Libreville"                "Africa/Lome"
 [35] "Africa/Luanda"                    "Africa/Lubumbashi"
 [37] "Africa/Lusaka"                    "Africa/Malabo"
 [39] "Africa/Maputo"                    "Africa/Maseru"
 [41] "Africa/Mbabane"                   "Africa/Mogadishu"
 [43] "Africa/Monrovia"                  "Africa/Nairobi"
 [45] "Africa/Ndjamena"                  "Africa/Niamey"
 [47] "Africa/Nouakchott"                "Africa/Ouagadougou"
 [49] "Africa/Porto-Novo"                "Africa/Sao_Tome"
 [51] "Africa/Timbuktu"                  "Africa/Tripoli"
 [53] "Africa/Tunis"                     "Africa/Windhoek"
 [55] "America/Adak"                     "America/Anchorage"
 [57] "America/Anguilla"                 "America/Antigua"
 [59] "America/Araguaina"                "America/Argentina/Buenos_Aires"
 [61] "America/Argentina/Catamarca"      "America/Argentina/ComodRivadavia"
 [63] "America/Argentina/Cordoba"        "America/Argentina/Jujuy"
 [65] "America/Argentina/La_Rioja"       "America/Argentina/Mendoza"
 [67] "America/Argentina/Rio_Gallegos"   "America/Argentina/Salta"
 [69] "America/Argentina/San_Juan"       "America/Argentina/San_Luis"
 [71] "America/Argentina/Tucuman"        "America/Argentina/Ushuaia"
 [73] "America/Aruba"                    "America/Asuncion"
 [75] "America/Atikokan"                 "America/Atka"
 [77] "America/Bahia"                    "America/Bahia_Banderas"
 [79] "America/Barbados"                 "America/Belem"
 [81] "America/Belize"                   "America/Blanc-Sablon"
 [83] "America/Boa_Vista"                "America/Bogota"
 [85] "America/Boise"                    "America/Buenos_Aires"
 [87] "America/Cambridge_Bay"            "America/Campo_Grande"
 [89] "America/Cancun"                   "America/Caracas"
 [91] "America/Catamarca"                "America/Cayenne"
 [93] "America/Cayman"                   "America/Chicago"
 [95] "America/Chihuahua"                "America/Coral_Harbour"
 [97] "America/Cordoba"                  "America/Costa_Rica"
 [99] "America/Creston"                  "America/Cuiaba"
[101] "America/Curacao"                  "America/Danmarkshavn"
[103] "America/Dawson"                   "America/Dawson_Creek"
[105] "America/Denver"                   "America/Detroit"
[107] "America/Dominica"                 "America/Edmonton"
[109] "America/Eirunepe"                 "America/El_Salvador"
[111] "America/Ensenada"                 "America/Fort_Nelson"
[113] "America/Fort_Wayne"               "America/Fortaleza"
[115] "America/Glace_Bay"                "America/Godthab"
[117] "America/Goose_Bay"                "America/Grand_Turk"
[119] "America/Grenada"                  "America/Guadeloupe"
[121] "America/Guatemala"                "America/Guayaquil"
[123] "America/Guyana"                   "America/Halifax"
[125] "America/Havana"                   "America/Hermosillo"
[127] "America/Indiana/Indianapolis"     "America/Indiana/Knox"
[129] "America/Indiana/Marengo"          "America/Indiana/Petersburg"
[131] "America/Indiana/Tell_City"        "America/Indiana/Vevay"
[133] "America/Indiana/Vincennes"        "America/Indiana/Winamac"
[135] "America/Indianapolis"             "America/Inuvik"
[137] "America/Iqaluit"                  "America/Jamaica"
[139] "America/Jujuy"                    "America/Juneau"
[141] "America/Kentucky/Louisville"      "America/Kentucky/Monticello"
[143] "America/Knox_IN"                  "America/Kralendijk"
[145] "America/La_Paz"                   "America/Lima"
[147] "America/Los_Angeles"              "America/Louisville"
[149] "America/Lower_Princes"            "America/Maceio"
[151] "America/Managua"                  "America/Manaus"
[153] "America/Marigot"                  "America/Martinique"
[155] "America/Matamoros"                "America/Mazatlan"
[157] "America/Mendoza"                  "America/Menominee"
[159] "America/Merida"                   "America/Metlakatla"
[161] "America/Mexico_City"              "America/Miquelon"
[163] "America/Moncton"                  "America/Monterrey"
[165] "America/Montevideo"               "America/Montreal"
[167] "America/Montserrat"               "America/Nassau"
[169] "America/New_York"                 "America/Nipigon"
[171] "America/Nome"                     "America/Noronha"
[173] "America/North_Dakota/Beulah"      "America/North_Dakota/Center"
[175] "America/North_Dakota/New_Salem"   "America/Nuuk"
[177] "America/Ojinaga"                  "America/Panama"
[179] "America/Pangnirtung"              "America/Paramaribo"
[181] "America/Phoenix"                  "America/Port_of_Spain"
[183] "America/Port-au-Prince"           "America/Porto_Acre"
[185] "America/Porto_Velho"              "America/Puerto_Rico"
[187] "America/Punta_Arenas"             "America/Rainy_River"
[189] "America/Rankin_Inlet"             "America/Recife"
[191] "America/Regina"                   "America/Resolute"
[193] "America/Rio_Branco"               "America/Rosario"
[195] "America/Santa_Isabel"             "America/Santarem"
[197] "America/Santiago"                 "America/Santo_Domingo"
[199] "America/Sao_Paulo"                "America/Scoresbysund"
[201] "America/Shiprock"                 "America/Sitka"
[203] "America/St_Barthelemy"            "America/St_Johns"
[205] "America/St_Kitts"                 "America/St_Lucia"
[207] "America/St_Thomas"                "America/St_Vincent"
[209] "America/Swift_Current"            "America/Tegucigalpa"
[211] "America/Thule"                    "America/Thunder_Bay"
[213] "America/Tijuana"                  "America/Toronto"
[215] "America/Tortola"                  "America/Vancouver"
[217] "America/Virgin"                   "America/Whitehorse"
[219] "America/Winnipeg"                 "America/Yakutat"
[221] "America/Yellowknife"              "Antarctica/Casey"
[223] "Antarctica/Davis"                 "Antarctica/DumontDUrville"
[225] "Antarctica/Macquarie"             "Antarctica/Mawson"
[227] "Antarctica/McMurdo"               "Antarctica/Palmer"
[229] "Antarctica/Rothera"               "Antarctica/South_Pole"
[231] "Antarctica/Syowa"                 "Antarctica/Troll"
[233] "Antarctica/Vostok"                "Arctic/Longyearbyen"
[235] "Asia/Aden"                        "Asia/Almaty"
[237] "Asia/Amman"                       "Asia/Anadyr"
[239] "Asia/Aqtau"                       "Asia/Aqtobe"
[241] "Asia/Ashgabat"                    "Asia/Ashkhabad"
[243] "Asia/Atyrau"                      "Asia/Baghdad"
[245] "Asia/Bahrain"                     "Asia/Baku"
[247] "Asia/Bangkok"                     "Asia/Barnaul"
[249] "Asia/Beirut"                      "Asia/Bishkek"
[251] "Asia/Brunei"                      "Asia/Calcutta"
[253] "Asia/Chita"                       "Asia/Choibalsan"
[255] "Asia/Chongqing"                   "Asia/Chungking"
[257] "Asia/Colombo"                     "Asia/Dacca"
[259] "Asia/Damascus"                    "Asia/Dhaka"
[261] "Asia/Dili"                        "Asia/Dubai"
[263] "Asia/Dushanbe"                    "Asia/Famagusta"
[265] "Asia/Gaza"                        "Asia/Harbin"
[267] "Asia/Hebron"                      "Asia/Ho_Chi_Minh"
[269] "Asia/Hong_Kong"                   "Asia/Hovd"
[271] "Asia/Irkutsk"                     "Asia/Istanbul"
[273] "Asia/Jakarta"                     "Asia/Jayapura"
[275] "Asia/Jerusalem"                   "Asia/Kabul"
[277] "Asia/Kamchatka"                   "Asia/Karachi"
[279] "Asia/Kashgar"                     "Asia/Kathmandu"
[281] "Asia/Katmandu"                    "Asia/Khandyga"
[283] "Asia/Kolkata"                     "Asia/Krasnoyarsk"
[285] "Asia/Kuala_Lumpur"                "Asia/Kuching"
[287] "Asia/Kuwait"                      "Asia/Macao"
[289] "Asia/Macau"                       "Asia/Magadan"
[291] "Asia/Makassar"                    "Asia/Manila"
[293] "Asia/Muscat"                      "Asia/Nicosia"
[295] "Asia/Novokuznetsk"                "Asia/Novosibirsk"
[297] "Asia/Omsk"                        "Asia/Oral"
[299] "Asia/Phnom_Penh"                  "Asia/Pontianak"
[301] "Asia/Pyongyang"                   "Asia/Qatar"
[303] "Asia/Qostanay"                    "Asia/Qyzylorda"
[305] "Asia/Rangoon"                     "Asia/Riyadh"
[307] "Asia/Saigon"                      "Asia/Sakhalin"
[309] "Asia/Samarkand"                   "Asia/Seoul"
[311] "Asia/Shanghai"                    "Asia/Singapore"
[313] "Asia/Srednekolymsk"               "Asia/Taipei"
[315] "Asia/Tashkent"                    "Asia/Tbilisi"
[317] "Asia/Tehran"                      "Asia/Tel_Aviv"
[319] "Asia/Thimbu"                      "Asia/Thimphu"
[321] "Asia/Tokyo"                       "Asia/Tomsk"
[323] "Asia/Ujung_Pandang"               "Asia/Ulaanbaatar"
[325] "Asia/Ulan_Bator"                  "Asia/Urumqi"
[327] "Asia/Ust-Nera"                    "Asia/Vientiane"
[329] "Asia/Vladivostok"                 "Asia/Yakutsk"
[331] "Asia/Yangon"                      "Asia/Yekaterinburg"
[333] "Asia/Yerevan"                     "Atlantic/Azores"
[335] "Atlantic/Bermuda"                 "Atlantic/Canary"
[337] "Atlantic/Cape_Verde"              "Atlantic/Faeroe"
[339] "Atlantic/Faroe"                   "Atlantic/Jan_Mayen"
[341] "Atlantic/Madeira"                 "Atlantic/Reykjavik"
[343] "Atlantic/South_Georgia"           "Atlantic/St_Helena"
[345] "Atlantic/Stanley"                 "Australia/ACT"
[347] "Australia/Adelaide"               "Australia/Brisbane"
[349] "Australia/Broken_Hill"            "Australia/Canberra"
[351] "Australia/Currie"                 "Australia/Darwin"
[353] "Australia/Eucla"                  "Australia/Hobart"
[355] "Australia/LHI"                    "Australia/Lindeman"
[357] "Australia/Lord_Howe"              "Australia/Melbourne"
[359] "Australia/North"                  "Australia/NSW"
[361] "Australia/Perth"                  "Australia/Queensland"
[363] "Australia/South"                  "Australia/Sydney"
[365] "Australia/Tasmania"               "Australia/Victoria"
[367] "Australia/West"                   "Australia/Yancowinna"
[369] "Brazil/Acre"                      "Brazil/DeNoronha"
[371] "Brazil/East"                      "Brazil/West"
[373] "Canada/Atlantic"                  "Canada/Central"
[375] "Canada/Eastern"                   "Canada/Mountain"
[377] "Canada/Newfoundland"              "Canada/Pacific"
[379] "Canada/Saskatchewan"              "Canada/Yukon"
[381] "CET"                              "Chile/Continental"
[383] "Chile/EasterIsland"               "CST6CDT"
[385] "Cuba"                             "EET"
[387] "Egypt"                            "Eire"
[389] "EST"                              "EST5EDT"
[391] "Etc/GMT"                          "Etc/GMT-0"
[393] "Etc/GMT-1"                        "Etc/GMT-10"
[395] "Etc/GMT-11"                       "Etc/GMT-12"
[397] "Etc/GMT-13"                       "Etc/GMT-14"
[399] "Etc/GMT-2"                        "Etc/GMT-3"
[401] "Etc/GMT-4"                        "Etc/GMT-5"
[403] "Etc/GMT-6"                        "Etc/GMT-7"
[405] "Etc/GMT-8"                        "Etc/GMT-9"
[407] "Etc/GMT+0"                        "Etc/GMT+1"
[409] "Etc/GMT+10"                       "Etc/GMT+11"
[411] "Etc/GMT+12"                       "Etc/GMT+2"
[413] "Etc/GMT+3"                        "Etc/GMT+4"
[415] "Etc/GMT+5"                        "Etc/GMT+6"
[417] "Etc/GMT+7"                        "Etc/GMT+8"
[419] "Etc/GMT+9"                        "Etc/GMT0"
[421] "Etc/Greenwich"                    "Etc/UCT"
[423] "Etc/Universal"                    "Etc/UTC"
[425] "Etc/Zulu"                         "Europe/Amsterdam"
[427] "Europe/Andorra"                   "Europe/Astrakhan"
[429] "Europe/Athens"                    "Europe/Belfast"
[431] "Europe/Belgrade"                  "Europe/Berlin"
[433] "Europe/Bratislava"                "Europe/Brussels"
[435] "Europe/Bucharest"                 "Europe/Budapest"
[437] "Europe/Busingen"                  "Europe/Chisinau"
[439] "Europe/Copenhagen"                "Europe/Dublin"
[441] "Europe/Gibraltar"                 "Europe/Guernsey"
[443] "Europe/Helsinki"                  "Europe/Isle_of_Man"
[445] "Europe/Istanbul"                  "Europe/Jersey"
[447] "Europe/Kaliningrad"               "Europe/Kiev"
[449] "Europe/Kirov"                     "Europe/Kyiv"
[451] "Europe/Lisbon"                    "Europe/Ljubljana"
[453] "Europe/London"                    "Europe/Luxembourg"
[455] "Europe/Madrid"                    "Europe/Malta"
[457] "Europe/Mariehamn"                 "Europe/Minsk"
[459] "Europe/Monaco"                    "Europe/Moscow"
[461] "Europe/Nicosia"                   "Europe/Oslo"
[463] "Europe/Paris"                     "Europe/Podgorica"
[465] "Europe/Prague"                    "Europe/Riga"
[467] "Europe/Rome"                      "Europe/Samara"
[469] "Europe/San_Marino"                "Europe/Sarajevo"
[471] "Europe/Saratov"                   "Europe/Simferopol"
[473] "Europe/Skopje"                    "Europe/Sofia"
[475] "Europe/Stockholm"                 "Europe/Tallinn"
[477] "Europe/Tirane"                    "Europe/Tiraspol"
[479] "Europe/Ulyanovsk"                 "Europe/Uzhgorod"
[481] "Europe/Vaduz"                     "Europe/Vatican"
[483] "Europe/Vienna"                    "Europe/Vilnius"
[485] "Europe/Volgograd"                 "Europe/Warsaw"
[487] "Europe/Zagreb"                    "Europe/Zaporozhye"
[489] "Europe/Zurich"                    "Factory"
[491] "GB"                               "GB-Eire"
[493] "GMT"                              "GMT-0"
[495] "GMT+0"                            "GMT0"
[497] "Greenwich"                        "Hongkong"
[499] "HST"                              "Iceland"
[501] "Indian/Antananarivo"              "Indian/Chagos"
[503] "Indian/Christmas"                 "Indian/Cocos"
[505] "Indian/Comoro"                    "Indian/Kerguelen"
[507] "Indian/Mahe"                      "Indian/Maldives"
[509] "Indian/Mauritius"                 "Indian/Mayotte"
[511] "Indian/Reunion"                   "Iran"
[513] "Israel"                           "Jamaica"
[515] "Japan"                            "Kwajalein"
[517] "Libya"                            "MET"
[519] "Mexico/BajaNorte"                 "Mexico/BajaSur"
[521] "Mexico/General"                   "MST"
[523] "MST7MDT"                          "Navajo"
[525] "NZ"                               "NZ-CHAT"
[527] "Pacific/Apia"                     "Pacific/Auckland"
[529] "Pacific/Bougainville"             "Pacific/Chatham"
[531] "Pacific/Chuuk"                    "Pacific/Easter"
[533] "Pacific/Efate"                    "Pacific/Enderbury"
[535] "Pacific/Fakaofo"                  "Pacific/Fiji"
[537] "Pacific/Funafuti"                 "Pacific/Galapagos"
[539] "Pacific/Gambier"                  "Pacific/Guadalcanal"
[541] "Pacific/Guam"                     "Pacific/Honolulu"
[543] "Pacific/Johnston"                 "Pacific/Kanton"
[545] "Pacific/Kiritimati"               "Pacific/Kosrae"
[547] "Pacific/Kwajalein"                "Pacific/Majuro"
[549] "Pacific/Marquesas"                "Pacific/Midway"
[551] "Pacific/Nauru"                    "Pacific/Niue"
[553] "Pacific/Norfolk"                  "Pacific/Noumea"
[555] "Pacific/Pago_Pago"                "Pacific/Palau"
[557] "Pacific/Pitcairn"                 "Pacific/Pohnpei"
[559] "Pacific/Ponape"                   "Pacific/Port_Moresby"
[561] "Pacific/Rarotonga"                "Pacific/Saipan"
[563] "Pacific/Samoa"                    "Pacific/Tahiti"
[565] "Pacific/Tarawa"                   "Pacific/Tongatapu"
[567] "Pacific/Truk"                     "Pacific/Wake"
[569] "Pacific/Wallis"                   "Pacific/Yap"
[571] "Poland"                           "Portugal"
[573] "PRC"                              "PST8PDT"
[575] "ROC"                              "ROK"
[577] "Singapore"                        "Turkey"
[579] "UCT"                              "Universal"
[581] "US/Alaska"                        "US/Aleutian"
[583] "US/Arizona"                       "US/Central"
[585] "US/East-Indiana"                  "US/Eastern"
[587] "US/Hawaii"                        "US/Indiana-Starke"
[589] "US/Michigan"                      "US/Mountain"
[591] "US/Pacific"                       "US/Samoa"
[593] "UTC"                              "W-SU"
[595] "WET"                              "Zulu"
attr(,"Version")
[1] "2022f"

Définissons le fuseau horaire sur GMT (Greenwich Mean Time) :

ymd_hms("2011-06-04 12:00:00", tz="GMT")
[1] "2011-06-04 12:00:00 GMT"

Les dates, les heures et les intervalles de temps sont abordés en détail dans des chapitres ultérieurs.

4.1.7 Factor vector (facteur)

Les facteurs sont des variables catégorielles, comme le sexe, la couleur des cheveux, l'origine ethnique, le statut pathologique, etc. Un facteur est tout simplement une variable catégorielle qui peut avoir plusieurs niveaux. Les niveaux peuvent avoir un ordre intrinsèque, mais ce n'est pas obligatoire. De nombreux nouveaux utilisateurs ont du mal à distinguer factor de character. La principale différence pratique est que, dans les calculs, R utilise presque toujours factor. Si une variable est de type character, R la convertit le plus souvent en factor avant d'effectuer le calcul. Il vous faudra parfois convertir vous-même un character en factor, ce que vous faites avec la fonction [as.factor()](https://rdrr.io/r/base/factor.html).

my_diagnoses <- c("Cancer", "Cancer", "Heart Disease", "Heart Disease", "Heart Disease")

my_diagnoses_character <- as.character(my_diagnoses)

my_diagnoses_factor <- as.factor(my_diagnoses)

Créons un tableau pour chaque vecteur. Le tableau indique le nombre d'observations de chaque niveau (catégorie) :

table(my_diagnoses_character)
my_diagnoses_character
       Cancer Heart Disease
            2             3
table(my_diagnoses_factor)
my_diagnoses_factor
       Cancer Heart Disease
            2             3

Il est donc possible de tabuler (créer un tableau) aussi bien avec un character qu'avec un factor. Utilisons la fonction [levels()](https://rdrr.io/r/base/levels.html) pour voir quels niveaux figurent dans ces vecteurs :

levels(my_diagnoses_character)
NULL
levels(my_diagnoses_factor)
[1] "Cancer"        "Heart Disease"

Comme on le voit ci-dessus, un vecteur character n'a pas de levels (niveaux). La fonction [levels()](https://rdrr.io/r/base/levels.html) renvoie NULL lorsqu'elle est appliquée à un vecteur character. En revanche, lorsque nous appliquons [levels()](https://rdrr.io/r/base/levels.html) à un factor, nous obtenons les niveaux de ce facteur.

Les facteurs ont un niveau de référence (reference level)

Tous les vecteurs de type factor ont un niveau de référence (reference level), c'est-à-dire la catégorie ou le niveau auquel toutes les autres catégories ou tous les autres niveaux sont comparés dans différents types de calculs. Le niveau de référence est en fait le premier affiché lorsque vous utilisez [levels()](https://rdrr.io/r/base/levels.html). Le niveau de référence du vecteur my_diagnoses_factor est donc Cancer.

Vous pouvez modifier le niveau de référence d'un factor, ce qui est souvent nécessaire lorsqu'on construit des tableaux descriptifs, des graphiques et des modèles statistiques. Pour le comprendre, prenons un exemple avec des données de cancérologie. Dans une étude, on souhaite comparer la survie des patients atteints d'un cancer du poumon en fonction de l'année de leur diagnostic. L'objectif est de déterminer si la survie s'est améliorée au fil des années ; à cette fin, on réalise une régression logistique dans laquelle chaque année civile est comparée à la dernière année de l'étude. Malheureusement, R a défini la première année (2017) comme niveau de référence, comme le montre l'exemple ci-dessous :

## Créer un vecteur d'années de diagnostic
cancer_diagnosis_year <- c("2020", "2022", "2019", "2017", "2022")

## Convertir le vecteur en factor
cancer_diagnosis_year <- as.factor(cancer_diagnosis_year)

## Vérifier les niveaux. Le premier niveau est le niveau de référence
levels(cancer_diagnosis_year)
[1] "2017" "2019" "2020" "2022"

Nous pouvons modifier cela à l'aide de la fonction [relevel()](https://rdrr.io/r/stats/relevel.html), de la façon suivante :

## Relevel
cancer_diagnosis_year <- relevel(cancer_diagnosis_year, "2022")

## Vérifier à nouveau les levels
levels(cancer_diagnosis_year)
[1] "2022" "2017" "2019" "2020"

4.2 Coercion (conversion forcée)

Vous avez déjà vu quelques exemples de coercion, ce qui signifie que R force (impose) certaines conversions de types de données. Les cas de coercion les plus fréquents surviennent dans les situations suivantes :

  • Si un vecteur contient un seul symbole ou caractère non numérique, l'ensemble du vecteur est converti en vecteur de type character, même s'il s'agit en réalité d'un vecteur numérique et que le caractère ou le symbole s'y est glissé par erreur.
  • Si un vecteur ne contient que des valeurs numériques, R le convertit en double.
  • Si un vecteur ne contient que des 0/1, il est converti en double, même s'il est censé être un vecteur de type logical.
  • Si un vecteur ne contient que des TRUE/FALSE, il est converti en logical.

Vous pouvez toujours convertir des vecteurs avec les fonctions [as.numeric()](https://rdrr.io/r/base/numeric.html), [as.factor()](https://rdrr.io/r/base/factor.html), [as.logical()](https://rdrr.io/r/base/logical.html), [as.character()](https://rdrr.io/r/base/character.html).

Mathématiquement, TRUE est interprété comme 1 et FALSE comme 0. On peut le vérifier en créant un vecteur de TRUE et de FALSE et en calculant la somme du vecteur avec la fonction [sum()](https://rdrr.io/r/base/sum.html) :

sum(c(TRUE, TRUE, FALSE, FALSE))
[1] 2

Vous pouvez convertir 0 et 1 en TRUE et FALSE de la façon suivante :

as.logical(c(1, 0, 1, 1))
[1]  TRUE FALSE  TRUE  TRUE

Et inversement :

as.numeric(c(TRUE, TRUE, FALSE, FALSE))
[1] 1 1 0 0

4.3 Attributes (attributs)

Les attributs sont des informations ou des précisions supplémentaires ajoutées à des vecteurs ou à des objets. Les attributs sont utiles dans de nombreux contextes. L'attribut le plus courant dans R est names, qui contient les noms des éléments d'un objet. Dans un data frame (tableau), il s'agit tout simplement des noms des colonnes.

4.3.1 Names

Créons un data frame de deux colonnes (variables), à savoir le sexe et la pression artérielle. Pour cela, nous créons d'abord deux vecteurs (gender, blood_pressure), que nous combinons ensuite en un data frame avec la fonction [data.frame()](https://rdrr.io/r/base/data.frame.html) :

gender <- c("Man", "Woman", "Man", "Woman")
blood_pressure <- c(140, 130, 120, 150)
my_data_frame <- data.frame(gender, blood_pressure)

Examinons notre data frame :

my_data_frame
  gender blood_pressure
1    Man            140
2  Woman            130
3    Man            120
4  Woman            150

Notre data frame comporte 4 lignes et 2 colonnes (variables). Vérifions les names (noms des colonnes) de notre data frame :

names(my_data_frame)
[1] "gender"    "blood_pressure"

Il existe deux attributs de nom : gender et blood_pressure.

Vous pouvez modifier les noms des colonnes en remplaçant l'information contenue dans names par une nouvelle information. Cela se fait de la façon suivante :

names(my_data_frame) <- c("Sex", "Pressure")
names(my_data_frame)
[1] "Sex"      "Pressure"

Il existe heureusement des méthodes plus simples pour renommer des colonnes ; elles sont présentées dans des chapitres ultérieurs.

Les attributs peuvent servir à faire référence au contenu des objets. Cela signifie que vous pouvez accéder à des colonnes précises d'un data frame en utilisant l'attribut. Pour faire référence à Pressure dans my_data_frame, vous utilisez le symbole $, de la façon suivante :

my_data_frame$Pressure
[1] 140 130 120 150

De la même manière, vous pouvez créer une nouvelle colonne. Créons maintenant la colonne Pressure_Half en divisant Pressure par 2 :

my_data_frame$Pressure_Half <- my_data_frame$Pressure/2

## Afficher notre data frame
my_data_frame
    Sex Pressure Pressure_Half
1   Man      140            70
2 Woman      130            65
3   Man      120            60
4 Woman      150            75

Voilà donc comment créer des colonnes à partir de colonnes existantes.

4.3.2 Dimensions

Vérifions l'attribut dim, abréviation de dimension. Cette fonction renvoie les dimensions de l'objet, c'est-à-dire le nombre de lignes et le nombre de colonnes pour un data frame (tableau) :

dim(my_data_frame)
[1] 4 3

La fonction [dim()](https://rdrr.io/r/base/dim.html) a renvoyé les nombres 4 et 3, qui représentent respectivement le nombre de lignes et le nombre de colonnes.

4.4 Matrix (matrice)

Angl. : singulier = matrix, pluriel = matrices.

Fr : singulier = matrice, pluriel = matrices.

Une matrix (matrice) est une structure à deux dimensions. Vous créez des matrices avec la fonction [matrix()](https://rdrr.io/r/base/matrix.html). Cette fonction possède les arguments nrow (nombre de lignes) et ncol (nombre de colonnes), qui définissent le nombre de lignes et de colonnes. Créons d'abord un vecteur numérique, puis une matrice à partir de celui-ci :

## Créer un vecteur de nombres
my_vector <- c(1, 2, 3, 4, 5, 6)

## Transformer le vecteur en une matrice de 2 lignes et 3 colonnes
my_matrix <- matrix(my_vector, nrow=2, ncol=3)

## Afficher la matrice
my_matrix
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

La fonction matrix() remplit la matrice de haut en bas, une colonne à la fois. Vous pouvez modifier ce comportement pour qu'elle remplisse plutôt une ligne à la fois, avec l'argument byrow=TRUE :

my_matrix <- matrix(my_vector, nrow=2, ncol=3, byrow=TRUE)

## Afficher la matrice
my_matrix
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

Une matrice ne peut contenir qu'un seul type de vecteur. C'est la grande différence entre les matrices et les data frames. Un data frame peut contenir tous les types de vecteurs (factor, character, numeric, double, integer, etc.).

4.5 Array

Un array peut avoir plus de deux dimensions. Un array peut donc être considéré comme un objet contenant plusieurs matrices distinctes. La fonction [array()](https://rdrr.io/r/base/array.html) utilise l'argument dim pour définir la structure de l'array. Pour créer un array de 2 lignes, 2 colonnes et 3 dimensions, utilisez la commande suivante :

my_vector <- c(1, 2, 3, 4, 5, 6)
my_array <- array(my_vector, dim=c(2, 2, 2))

## View my_array
my_array
, , 1
     [,1] [,2]
[1,]    1    3
[2,]    2    4
, , 2
     [,1] [,2]
[1,]    5    1
[2,]    6    2

Si un array est plus grand que le nombre d'éléments du vecteur sur lequel il repose, le vecteur est recyclé, comme le montre l'exemple ci-dessus (les chiffres 1 et 2 ont été réutilisés dans la deuxième colonne de la seconde matrice).

4.6 Lists (listes)

Les listes sont des objets puissants, car elles peuvent stocker tous les types d'objets. Une liste peut donc contenir simultanément plusieurs vecteurs, data frames, matrices et arrays. Les objets peuvent même avoir des longueurs différentes ! Les listes sont créées avec la fonction [list()](https://rdrr.io/r/base/list.html). Créons une liste contenant des vecteurs de type character, numeric et logical (notez que les vecteurs ont des longueurs différentes) :

## Vecteur numérique
my_numbers <- c(1, 2, 3)

## Vecteur character
my_characters <- c("Diabetes", "Cancer", "AIDS", "Heart failure", "Arthritis", "Depression")

## Vecteur logical
my_bools <- c(TRUE, TRUE, FALSE, TRUE)

## Combiner les vecteurs en une liste
my_list <- list(my_numbers, my_characters, my_bools)

## Afficher la liste
my_list
[[1]]
[1] 1 2 3
[[2]]
[1] "Diabetes"      "Cancer"        "AIDS"          "Heart failure"
[5] "Arthritis"     "Depression"
[[3]]
[1]  TRUE  TRUE FALSE  TRUE

Notez les points suivants :

  • Les vecteurs stockés dans une liste peuvent être de longueur et de type de données variables.
  • L'affichage ci-dessus montre que la liste contient 3 objets, indiqués par [1[1], [2[2] et [3[3]. Pour faire référence aux objets d'une liste, on utilise donc des doubles crochets.

Une liste peut même contenir un data frame. Développons l'exemple ci-dessus en y ajoutant un data frame, puis affichons la liste :

## Vecteur numérique
my_numbers <- c(1, 2, 3)

## Vecteur character
my_characters <- c("Diabetes", "Cancer", "AIDS", "Heart failure", "Arthritis", "Depression")

## Vecteur logical
my_bools <- c(TRUE, TRUE, FALSE, TRUE)

## Data frame
age <- c(1, 2, 3, 4)
sex <- c("male", "female", "male", "female")
my_data_frame <- data.frame(age, sex)

## Combiner le tout en une liste
my_list <- list(my_numbers, my_characters, my_bools, my_data_frame)

## Afficher la liste
my_list
[[1]]
[1] 1 2 3
[[2]]
[1] "Diabetes"      "Cancer"        "AIDS"          "Heart failure"
[5] "Arthritis"     "Depression"
[[3]]
[1]  TRUE  TRUE FALSE  TRUE
[[4]]
  age    sex
1   1   male
2   2 female
3   3   male
4   4 female

Le premier objet de la liste ([1[1]) stocke les valeurs 1, 2 et 3. Le deuxième objet de la liste ([2[2]) stocke les chaînes de caractères Diabetes, Cancer, AIDS, etc.

Les listes sont très flexibles : elles peuvent même contenir d'autres listes. En voici un exemple :

## Create atomic vector
my_numbers <- c(1, 2, 3)

## Create a list
my_first_list <- list(c("A", "B", "C"), c(100, 200, 300))

## Create a list storing both an atomic vector and a list
my_second_list <- list(my_numbers, my_first_list)

## View my list
my_second_list
[[1]]
[1] 1 2 3
[[2]]
[[2]][[1]]
[1] "A" "B" "C"
[[2]][[2]]
[1] 100 200 300

Vous pouvez maintenant voir que le nouvel objet contient trois lignes mais seulement deux objets ; le deuxième objet ([2[2]) est toutefois une liste et contient deux objets. Il est important de noter qu'une liste peut contenir tous les types d'objets R, ce qui rend les listes utiles pour le stockage de données.

4.7 Data frames

Nous avons déjà vu plusieurs data frames dans les exemples ci-dessus. Un data frame ressemble à une feuille de calcul Excel ou Numbers. Dans un data frame typique, chaque ligne correspond à une observation et les colonnes constituent les variables :

Nom Âge Revenu Niveau d'études Cholestérol
Adam 45 324211 Enseignement supérieur 4,5
Zara 51 198765 Scolarité obligatoire 7,6
John 49 250643 Lycée 3,2

Exemple de data frame.

Dans la majorité des cas, les lignes correspondent aux observations et les colonnes aux mesures (variables) effectuées sur ces observations. Les modèles statistiques, le machine learning et d'autres fonctions courantes de R exigent souvent que les données se trouvent dans un data frame. Créons maintenant trois vecteurs et combinons-les en un data frame.

## Crée un vecteur contenant les nombres de 1 à 15
variable1 <- 1:15

## Utilise la fonction rnorm() pour générer 15 valeurs entièrement aléatoires
variable2 <- rnorm(15)

## Crée un vecteur de 15 lettres </em>
variable3 <- c("A", "B", "W", "C", "D", "E", "A", "B", "C", "D", "E", "U", "O", "L", "E")

## Combine le tout en un data frame avec la fonction data.frame()
my_data_frame <- data.frame(variable1, variable2, variable3)

## Afficher notre data frame
my_data_frame
   variable1   variable2 variable3
1          1  0.61687819         A
2          2 -1.49693238         B
3          3 -0.02426337         W
4          4  0.97459121         C
5          5 -1.03211448         D
6          6 -0.57205032         E
7          7 -0.30575213         A
8          8 -0.77495326         B
9          9 -0.67784625         C
10        10  0.50121613         D
11        11  1.23014030         E
12        12 -1.84284583         U
13        13  0.16945138         O
14        14  0.91849363         L
15        15  0.69476883         E

Chaque colonne de notre data frame contient le même type de données et les vecteurs ont la même longueur. Si les vecteurs n'ont pas la même longueur, R recycle le vecteur le plus court pour créer un data frame.

Pourquoi tant de complications ?

Dans les exemples ci-dessus, nous avons créé des vecteurs et des data frames manuellement. C'est indéniablement long et fastidieux. Dans votre travail, vous importerez très probablement un data frame tout prêt que vous analyserez ensuite. Si nous avons malgré tout créé des vecteurs et des data frames manuellement, c'est pour montrer comment R se comporte.

Vérifions la structure de notre data frame à l'aide de la fonction [str()](https://rdrr.io/r/utils/str.html) :

str(my_data_frame)
'data.frame':   15 obs. of  3 variables:
 $ variable1: int  1 2 3 4 5 6 7 8 9 10 ...
 $ variable2: num  0.6169 -1.4969 -0.0243 0.9746 -1.0321 ...
 $ variable3: chr  "A" "B" "W" "C" ...

D'après ce qui précède, l'objet est de type « data.frame », avec 15 observations et 3 variables. On constate que variable1 est de type integer, variable2 est numeric et variable3 est character. Lorsque vous créez un data frame, vous pouvez indiquer si vous souhaitez que R convertisse les vecteurs character en factors avec l'argument stringsAsFactors, de la façon suivante :

my_data_frame <- data.frame(variable1, variable2, variable3, stringsAsFactors = TRUE)
str(my_data_frame)
'data.frame':   15 obs. of  3 variables:
 $ variable1: int  1 2 3 4 5 6 7 8 9 10 ...
 $ variable2: num  0.6169 -1.4969 -0.0243 0.9746 -1.0321 ...
 $ variable3: Factor w/ 9 levels "A","B","C","D",..: 1 2 9 3 4 5 1 2 3 4 ...

variable3 est désormais un factor à 9 levels (niveaux).

Icône d'une fenêtre de programme avec trois boutons colorés et des lignes de code vertes sur fond sombre

Data frame = df

Il est courant d'abréger data frame en df. Vous rencontrerez souvent cette abréviation lorsque vous travaillerez avec R.