Objets

Considérez maintenant la ligne suivante :

assign(x = "x", val = seq(from = 1, to = 10, by = 1))

Ou, ce qui est strictement équivalent :

assign("x", 1:10)

Lorsque vous aurez exécuté cette ligne, vous pourrez constater qu’en tapant x dans la console :

> x
[1]  1  2  3  4  5  6  7  8  9 10

Vous avez créé un objet nommé x auquel, en utilisant la fonction assign, vous avez assigné la valeur de 1:10. C’est-à-dire que dorénavant, à moins que vous supprimiez x ou que vous lui donniez une autre valeur, R connait un objet nommé x qui contient la séquence de tous les nombres entiers de 1 à 10.

La fonction ls (ici sans argument) vous permet de lister tous les objets qui existent dans votre espace de travail :

> ls()
[1] "x"

Cette notion d’espace de travail (.GlobalEnv de son petit nom) est importante : par analogie, vous pouvez considérer que c’est l’équivalent de la surface de votre bureau ; surface sur laquelle vous avez déposé un objet nommé x ; objet que vous allez donc pouvoir manipuler. Par exemple, si vous souhaitez connaitre la somme des éléments de x, utilisez la fonction sum :

> sum(x)
[1] 55

Vous pouvez déposer d’autres objets dans votre espace de travail :

> assign(x = "y", rep(1:5, 2))

Pour créer y, j’ai utilisé la fonction rep (pour repeat) avec pour arguments x = 1:5 (soit la séquence des entiers de 1 à 5) et times = 2. Ce qui nous donne :

> y
 [1] 1 2 3 4 5 1 2 3 4 5

Et :

> ls()
[1] "x" "y"

Puisque nous y sommes, nous allons aussi créer z :

> assign("z", c(.1, 1, .5, 1.1, .9, .2, 1.2, -.1, .8, 1.3))
> z
 [1]  0.1  1.0  0.5  1.1  0.9  0.2  1.2 -0.1  0.8  1.3

Ici, pour créer z, j’ai utilisé la fonction c qui permet de concaténer à peu près n’importe quoi.

Si vous faites l’inventaire de votre espace de travail :

> ls()
[1] "x" "y" "z"

Vous constatez que vous disposez désormais de trois objets (x, y et z) avec lesquels vous pouvez jouer.

Vous pouvez, par exemple, calculer la longueur de x :

> length(x)
[1] 10

Trouver le maximum de z :

> max(z)
[1] 1.3

« Coller » x et z bout à bout :

> c(x, z)
[1]  1.0  2.0  3.0  4.0  5.0  6.0  7.0  8.0  9.0 10.0
[11] 0.1  1.0  0.5  1.1  0.9  0.2  1.2 -0.1  0.8  1.3

Trouver les éléments communs aux deux :

> intersect(x, z)
[1] 1

Bref, vous pouvez faire à peu près ce que vous voulez de vos trois jouets.

Notez bien que si vous exécutez :

> assign("x", rev(z))

Vous avez toujours trois objets en mémoire (x, y et z) :

> ls()
[1] "x" "y" "z"

Mais la valeur de x a changé :

> x
 [1]  1.3  0.8 -0.1  1.2  0.2  0.9  1.1  0.5  1.0  0.1

En assignant rev(z) à x (rev pour reverse), vous avez écrasé l’ancien x et l’avez remplacé par un nouveau x qui n’est rien d’autre que z mais dans l’autre sens.

De la même manière que : est un opérateur pour la fonction seq, la fonction assign dispose de son propre opérateur.

Elle en a même plusieurs : principalement <-, -> et =.

C’est-à-dire que notre :

assign("x", -10:10)

Peut aussi s’écrire :

x <- -10:10

Ou :

-10:10 -> x

Ou encore :

x = -10:10

En pratique, je vous recommande d’éviter d’utiliser = qui peut prêter à confusion et je vous suggère d’utiliser surtout <-. Retenez bien cet opérateur : nous allons l’utiliser tout le temps.

Reprenez votre script, effacez tout et écrivez ceci :

rm(list = ls())

La fonction rm supprime les objets passés à son argument list. Comme ls liste les objets qui trainent dans votre espace de travail, cette première ligne de code nettoie ledit espace de travail :

> rm(list = ls())
> ls()
character(0)

À ce stade, donc, vous n’avez plus aucun objet en mémoire. C’est-à-dire que :

> x
Erreur : objet 'x' introuvable

Nous allons donc en recréer un pour pouvoir continuer à jouer. Pour changer un peu, nous allons l’appeler value :

Complétez votre script :

rm(list = ls())
value <- head(rivers, 15)

Pour créer value, j’ai utilisé un set de données que R nous fournit pour nous permettre de tester des choses. En l’occurrence, j’ai utilisé rivers (la longueur en kilomètres des plus grands cours d’eau d’Amérique du nord... mais peu importe). Dans la console, vous pouvez exécuter :

> rivers
  [1]  735  320  325  392  524  450 1459  135  465  600  330  336  280  315
 [15]  870  906  202  329  290 1000  600  505 1450  840 1243  890  350  407
 [29]  286  280  525  720  390  250  327  230  265  850  210  630  260  230
 [43]  360  730  600  306  390  420  291  710  340  217  281  352  259  250
 [57]  470  680  570  350  300  560  900  625  332 2348 1171 3710 2315 2533
 [71]  780  280  410  460  260  255  431  350  760  618  338  981 1306  500
 [85]  696  605  250  411 1054  735  233  435  490  310  460  383  375 1270
 [99]  545  445 1885  380  300  380  377  425  276  210  800  420  350  360
[113]  538 1100 1205  314  237  610  360  540 1038  424  310  300  444  301
[127]  268  620  215  652  900  525  246  360  529  500  720  270  430  671
[141] 1770

Vous constatez que rivers est de longueur 141 :

> length(rivers)
[1] 141

Or, il se trouve que je souhaite que value ne contienne que les 15 premiers éléments de rivers : j’ai donc utilisé la fonction head qui sélectionne les n = 15 premiers éléments de l’objet qu’on lui passe en premier argument (x = rivers).

Effectivement :

> value
 [1]  735  320  325  392  524  450 1459  135  465  600  330  336  280  315
[15]  870

Dans R, cet objet est un vecteur de classe numeric ou, pour faire simple, un vecteur numérique :

> class(value)
[1] "numeric"

N’ayez pas peur ! Un vecteur numérique ce n’est rien d’autre qu’une suite ordonnée de nombre ; par ordonnée, pour devez entendre que chaque élément du vecteur a une position bien définie : dans le cas de value, nous avons 735 en première position, puis 320 en deuxième position, puis 325 etc... Ce n’est rien d’autre que ça.

Dans R, une classe est une famille d’objets qui partagent les mêmes caractéristiques et sont traités de la même manière. La classe numeric, par exemple, regroupe les vecteurs qui contiennent des données numériques. Elle a quelques cousines proches comme les vecteurs de classe integer que nous allons voir dans un instant.

Il existe potentiellement une infinité de classes d’objets dans R puisque vous pouvez créer de toutes pièces des nouvelles classes mais nous n’allons passer en revu que les principaux.

Donc, value est un vecteur numérique. Comme tous les vecteurs, il n’a pas de dimensions :

> dim(value)
NULL

Mais il a une longueur :

> length(value)
[1] 15

Ça peut — à bon droit — vous sembler un peu étrange puisque si value a une longueur, il a bien une dimension : sa longueur justement. C’est une petite bizarrerie ; il faut faire avec.

J’évoquais plus hauts les vecteurs de classe integer ; nous allons en créer un :

years <- seq(2000, by = 1, len = length(value))

Vous pouvez vérifier que :

> class(years)
[1] "integer"

C’est-à-dire que years est aussi un vecteur numérique mais, comme il ne contient que des nombres entiers, il appartient à la classe integer (désormais, par abus de langage, je désignerais sous le nom de vecteurs numériques des objets numeric et integer indifféremment).

Dans la grande famille des vecteurs, vous rencontrerez aussi les vecteurs de classe character qui — comme leur nom le suggère — contiennent du texte. Par exemple, en utilisant letters (les lettres de l’alphabet latin) et la fonction tail (qui sélectionne les n derniers éléments de son premier argument), on peut créer alpha :

alpha <- tail(letters, 15)

Vous observez que :

> alpha
[1] "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
> class(alpha)
[1] "character"

Notez que dans R, tout ce qui apparait entre doubles guillemets est du texte (donc de classe character). Par exemple :

> test <- c("100", "101", "102")
> test
[1] "100" "101" "102"
> class(test)
[1] "character"

Dans ce cas, vous pouvez :

> as.numeric(test)
[1] 100 101 102

Il existe aussi une classe Date (avec un D majuscule, c’est comme ça) :

dates <- as.Date("2000-01-01") + 0:14

Et :

> class(dates)
[1] "Date"

Enfin, pour en finir avec les principaux types de vecteurs, il existe aussi une classe logical :

logic <- value > median(value)

Ce qui nous donne :

> logic 
 [1]  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE
[13] FALSE FALSE  TRUE
> class(logic)
[1] "logical"

Si vous avez déjà codé dans un autre langage, vous avez reconnu les booléens (Vrai/Faux).

Récapitulons. Nous avons vu cinq familles de vecteurs : ceux qui contiennent des nombres (numeric et integer), ceux qui contiennent du texte (character), ceux qui contiennent des dates (Date) et ceux qui contiennent des booléens (logical).

Avant de poursuivre, faisons un peu de ménage.

À ce stade :

> ls() 
[1] "alpha" "dates" "logic" "test"  "value" "years"

Nous n’avons plus besoin de test :

> rm(list = "test")
> ls() 
[1] "alpha" "dates" "logic" "value" "years"

Notez que si vous avez créé d’autres objets pour vous entraîner — ce qui est une excellente chose — vous pouvez les supprimer d’un coup en exécutant :

rm(list = c("test", "truc", "bidule", "machin"…))

Nous allons inspecter plus en détail ces cinq premières classes mais avant cela, le moment me semble bien choisi pour vous présenter un concept très important : l’indexation d’objets dans R.

Aucun commentaire:

Enregistrer un commentaire