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
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 -> variableLa 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 + 1a 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 - bon 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 - bon 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 6Il 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 dEn 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 7Comme 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:nnMaitriser 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 8De 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 incorrectSignalons 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 à la page principale de (gH)