Valid XHTML     Valid CSS2    

Introduction à la programmation avec R

                gilles.hunault "at" univ-angers.fr

Cours 2 - Affectations, structures de données et affichages

 

Table des matières cliquable

  1. Variables simples et affectations

  2. Structures de données et affectations en R

  3. Autres "objets" en R

  4. Affichage des variables en R

  5. Spécificités du langage R

 
Exercices :           énoncés            solutions           [Retour à la page principale du cours]

1. Variables simples et affectations

Une variable est semblable à une boite dotée d'un nom (ou identifiant) qui contient une valeur (nommée aussi contenu de la variable). Réaliser une affectation, c'est mettre une valeur dans une variable, qu'il s'agisse d'une valeur numérique ou caractère ou autre. Mettre une valeur dans une variable pour la première fois se nomme initialiser la variable. Contrairement à d'autres langages de programmation il n'y a pas besoin en R de prévenir ("déclarer" ou "typer" cette variable) en prévenant ce qu'elle va contenir, un nombre, du texte, etc. On utilise en R les symboles accolés tiret et supérieur (ce qui ressemble un peu à une flèche) pour indiquer le contenu et la variable. Deux syntaxes sont possibles en R :


     variable <- calcul
     calcul   -> variable
     

La première forme avec d'abord le nom de la variable est la plus classique mais la seconde est la plus explicite et sans doute la plus compréhensible. La machine commence toujours par évaluer (calculer) la partie du coté du tiret de la flèche, ce qui explique que l'instruction


     variable <- variable + 1
     

a un sens qui signifie rajouter un à la variable, ce qui se dit incrémenter la variable.

Lorsque la machine exécute "le code" (les instructions), elle procéde en séquence c'est-à-dire qu'elle exécute les instructions les unes à la suite des autres. C'est un peu un «jeu de piste» que de trouver ce que fait la machine lorsqu'on lit les instructions. Ainsi avec le code


     a <- 6
     b <- 3
     a <- a + b
     b <- a - b
     a <- a - b
     

on trouve 3 dans la variable a et 6 dans la variable b, ce qui se nomme permuter les variables alors qu'avec le code


     a <- 6
     b <- 3
     a <- a - b
     b <- a + b
     a <- a - b
     

on n'obtient rien de particulier (ou, plutôt, si,   on perd la valeur de a).

Conclusion : il faut être très prudent(e), bien se relire, bien tout vérifier car on a vite fait de se tromper, surtout si on tape vite sur le clavier.

Pour ceux et celles qui n'ont pas compris le détail de la permutation des variables, voici les explications écrites directement dans le code à l'aide de commentaires repérés par le symbole dièse (#). La machine ne tient pas compte du dièse et de ce qui le suit. Il est conseilé de mettre «suffisamment» de commentaires afin de pouvoir se relire et que les autres personnes qui lisent le code puisssent le comprendre.


     a <- 6         # a contient 6 et b n'existe pas pour l'instant
     b <- 3         # a contient 6 et b contient 3
     a <- a + b     # a contient 9 et b contient 3
     b <- a - b     # a contient 9 et b contient 6
     a <- a - b     # a contient 3 et b contient 6
     

Il existe bien sûr des solutions plus simples, plus générales pour réaliser cette permutation. Voir l'exercice 1.

Le choix du nom des variables (en particulier le nombre de lettres de l'identifiant) et la façon de les écrire ne sont pas imposés, mais il existe plusieurs méthodes et surtout quelques conseils de bon sens. Voir l'exercice 2.

2. Structures de données et affectations en R

R est un langage vectoriel ce qui signifie que les vecteurs sont les éléments de base du langage. On peut créer des vecteurs de différentes façons, par exemple avec la fonction c(), la fonction seq(), la fonction vector(), la fonction rep() ou son raccourci : (le symbole deux-points)... Grâce à la fonction identical(), il est facile de vérifier que x et c(x) représentent le même objet. Le nombre d'éléments d'un vecteur se nomme sa longueur et s'obtient en R à l'aide de la fonction length().


     x <- 2
     y <- c(2)
     print( identical(x,y) ) # la machine répond TRUE (vrai, en anglais)
     
     a <- 2
     b <- length(a)          # b contient 1
     c <- 5
     d <- c(a,b,c)           # le vecteur 2 1 5
     print( length(d) )      # la machine répond 3 car il y a trois éléments dans d
     
     

En R, a:b correspond aux vecteurs des entiers qui vont de a à b. Voici quelques exemples :


     1:5       #  le vecteur 1 2 3 4 5
     2:0       #  le vecteur 2 1 0
     
     n <- 6
     
     1:n+1     #  le vecteur 2 3 4 5 6 7
     (1:n)+1   #  le vecteur 2 3 4 5 6 7
     1:(n+1)   #  le vecteur 1 2 3 4 5 6 7
     

Comme le montrent les trois derniers exemples, R connait le calcul vectoriel : additionner 1 à un vecteur, c'est ajouter 1 à chacun des éléments du vecteur. De même, R sait additionner naturellement des vecteurs de même longueur, les multiplier... Il faut donc impérativement utiliser des parenthèses en cas de doute sur une opération ou réaliser une affectation supplémentaire pour obtenir un code lisible :


     # mettre les nombres de 1 à n+1 dans v (version 1)
     
     v <- 1:(n+1)
     
     # mettre les nombres de 1 à n+1 dans v (version 2)
     
     nn <- n+1
     v  <- 1:nn
     

Maitriser la notation deux-points et les opérations vectorielles élémentaires est très important parce que cela permet d'effectuer de nombreux calculs et de générer de nombreuses valeurs à moindre frappe. Voir l'exercice 3.

En plus des vecteurs, R dispose des listes comme élements de base. Une liste nommée (nous ne conseillons pas d'utiliser des listes non nommées) se définit via le mot anglais list() -- on s'en serait douté ! On accède aux éléments d'une liste nommée via leur nom et le symbole $ (dollar). Le nombre d'éléments d'une liste se nomme sa longueur et s'obtient en R à l'aide de la fonction length() mais attention car une liste peut contenir plein de choses, des vecteurs, d'autres listes, etc. Voici quelques exemple qui se veulent explicites :


     a <- list(b=3,c=4) # a est une liste qui contient b et c
     print( a$b )       # la machine affiche la valeur 3 (contenu de b)
     
     length(a)          # 2 car il y a deux éléments dans a
     names(a)           # correspond aux noms dans a, soit le vecteur "b" "c"
     
     # une écriture pratique :
     
     res <- list(methode="simple",
                 fichier="a35.xls",
                 jour=28
     ) # fin de list
     
     # on peut aussi commenter en partie droite
     
     xmp <- list(methode="simple",      # ceci montre comment on
                 fichier="a35.xls",     # peut avoir du code très
                 jour=28                # lisible pour une liste
     ) # fin de list
     
     # des listes plus générales :
     
     a <- 5
     b <- list(a=a,c=8)
     c <- 1:3
     d <- list(a,b,c,d=3)
     
     e <- list(x=1,y=c(2,3),z=list(a=4,b=5,c=6),t="bravo !")
     
     

3. Autres "objets" en R

R dispose aussi de deux structures de données très importantes issues des vecteurs et des listes : ce sont les matrices et les data frames qui permettent de représenter respectivement des tableaux homogènes et hétérogènes classiques avec des lignes et des colonnes. Nous y reviendrons plus tard. Signalons aussi qu'il existe des tableaux généraux (array) mais dont on se passe la plupart du temps !

Pour connaitre la nature d'on objet, on peut utiliser la fonction class() :


     a <- 2
     b <- c(1,5)
     c <- list(a,b)
     d <- "oui"
     
     class(a)   # renvoie "numeric"
     class(b)   # renvoie "numeric" aussi
     class(c)   # renvoie "list"
     class(d)   # renvoie "character"
     

R a aussi des valeurs "spéciales" nommées NA, et NULL dont nous reparlerons plus tard, comme les résultats Inf, NAN et <NA>.

Pour les plus impatient(e)s, le lien sous ces mots dans le tableau suivant mène à l'aide de R pour ces valeurs :

mot signification
 NA  Not Available
 NULL  Rien (!)
 NAN  Not a number (pas un nombre)
 Inf  Infini

Voir l'exercice 4.

4. Affichage des variables en R

On dispose de deux fonctions principales pour afficher les variables : la fonction print() et la fonction cat(). De plus on peut utiliser paste() et sprintf() pour respectivement concaténer des chaines ou les formater. Voici un petit pot-pourri qui montre la puissance de ces fonctions :


     > x <- 1
     > cat(" x vaut ",x,"\n")
       x vaut 1
     
     > n <- 10
     > v <- 1:n
     > cat(" on dispose des ",n,"valeurs : ")
       on dispose des  10 valeurs :
     > print(v)
       1  2  3  4  5  6  7  8  9 10
     
     > cat(" on change \n de ligne \n") ;
       on change
       de ligne
     
     > w <- sprintf("%03d",v)
     > cat(" données formatées")
       données formatées
     > print(w)
       "001" "002" "003" "004" "005" "006" "007" "008" "009" "010"
     
     > x <- paste(w,collapse=" ; ")
     > print(x)
       "001 ; 002 ; 003 ; 004 ; 005 ; 006 ; 007 ; 008 ; 009 ; 010"
     
     > print(paste("serie",(1:5),".xls",sep=""))
       "serie1.xls" "serie2.xls" "serie3.xls" "serie4.xls" "serie5.xls"
     
     > cat(1:3,"\n")
       1 2 3
     
     > x <- list(a=1,b=2,c=3)
     
     > # attention :
     > cat(x)
       Erreur dans cat(list(...), file, sep, fill, labels, append) :
       argument 1 (type 'list') pas encore traité par cat
     
     > # une solution partielle
     > cat( paste(x,sep=" "), "\n")
       1 2 3
     
     > e <- list(x=1,y=c(2,3),z=list(a=4,b=5,c=6),t="bravo !")
     > cat(paste(e,sep=" "),"\n")
       1 c(2, 3) list(a = 4, b = 5, c = 6) bravo !
     
     
     
     

5. Spécificités du langage R

R est un langage particulier puisqu'il est vectoriel. Du coup, on dispose facilement de séries de valeurs et de calculs idoines et en particulier on peut appliquer à des vecteurs des fonctions statistiques et mathématiques comme sum(), mean(), min, max...


     > # un vecteur
     
     > v <- c(1,8,2,7,4)
     
     > # exponentielle et logarithme des valeurs
     
     > print( exp(v) )
       [1]    2.718282 2980.957987    7.389056 1096.633158   54.598150
     
     > print( log(v) )
       [1] 0.0000000 2.0794415 0.6931472 1.9459101 1.3862944
     
     > # sprintf aussi est vectoriel :
     > print( sprintf("%6.1f", exp(v) ) )
       [1] "   2.7" "2981.0" "   7.4" "1096.6" "  54.6"
     
     > # sa moyenne et sa médiane
     
     > print( c(mean(v),median(v)) )
       [1] 4.4 4.0
     
     > # le min et le max
     
     > print( c(min(v),max(v)) )
       [1] 1 8
     
     > # la fonction range :
     
     > print( range(v) )
       [1] 1 8
     

De façon subtile, R distingue les entiers des réels. Ainsi 1 est un réel alors que 1L est un entier. Comme : renvoie des entiers, il est normal que 1:2 ne soit pas égal à c(1,2) mais bien à c(1L,2L).

Il faut aussi noter que les vecteurs sont toujours "plats", homogènes en type et que R convertit sans prévenir. Cela peut avoir de graves conséquences :


     > # un vecteur d'entier
     
     > x <- c(1L,8L)
     
     > cat(" nature : ",class(x)," somme (1) :",sum(x) )
       nature :  integer  somme (1) : 9
     
     > # on ajoute un réel
     
     > x <- c(x,2)
     
     > cat(" nature : ",class(x)," somme (2) :",sum(x) )
       nature :  numeric  somme (2) : 11
     
     > # un vecteur est toujours "plat"
     
     > x <- c( x, c(x,2) , 2 )
     
     > cat(" nature : ",class(x)," somme (2) :",sum(x) )
       nature :  numeric  somme (2) : 26
     
     > # on ajoute une chaine de caractères
     
     > x <- c(x,"oui")
     
     > cat(" nature : ",class(x)," somme (3) :",sum(x) )
       Erreur dans sum(x) : 'type' (character) de l'argument incorrect
     

Signalons au passage que les fonctions sont des variables et qu'on peut donc les inclure dans des listes...


     a <- 1L
     b <- 2
     c <- "oui"
     d <- sum
     e <- list(a=a,b=b,c=c,d=d)
     

Il faut noter que l'affectation est aussi une fonction. La notation <- n'est qu'un raccourci d'écriture :


     # en R, l'affectation est une fonction
     
        "<-"(x,1) # équivalent à x <- 1
     
     # une autre écriture :
     
        assign("x",1)
     

Enfin, terminons par le fait qu'en R la structure de données de base est le vecteur. a <- 1 fait de a un vecteur numérique de longueur 1. Nous vous laissons comprendre ce qui suit :


     > a <- 1
     > c(class(a),length(a))
     [1] "numeric" "1"
     
     > a[10] <- "oui"
     > print(  c(class(a),length(a)) )
     [1] "character" "10"
     
     > print(a)
      [1] "1"   NA    NA    NA    NA    NA    NA    NA    NA    "oui"
     > print(cbind(a))
      [1,] "1"
      [2,] NA
      [3,] NA
      [4,] NA
      [5,] NA
      [6,] NA
      [7,] NA
      [8,] NA
      [9,] NA
     [10,] "oui"
     

 
Exercices :           énoncés            solutions           [Retour à la page principale du cours]

 

 

retour gH    Retour à la page principale de   (gH)