Les instructions de contrôle dans R sont très semblables à celles C, C ++, Python et Perl. Ici, nous allons regarder les boucles et si, sinon Déclarations.
1 boucles
Dans les chapitres précedentes, nous avons défini la fonction oddcount (). Dans cette fonction, le code suivant avait été reconnu par les programmeurs Python:
for (n in x) {
Cela signifie qu'il y aura une itération de la boucle pour chaque composant du vecteur x, avec n prenant les valeurs de ces composants dans la premiere itération, n = x [1]; dans la deuxième itération, n = x [2]; etc. Par exemple, le code suivant utilise cette structure pour afficher le carré de chaque élément dans un vecteur:
> x <- c (5,12,13)
> for (n in x) print (n ^ 2)
[1] 25
[1] 144
[1] 169
La boucle de style C avec while et repeat est également disponible, complète avec break, une déclaration qui permet de quitter la boucle. Voici un exemple:
> i <- 1
> while (i <= 10) i <- i + 4
> i
[1] 13
>
> i <- 1
> while (TRUE) {# similaire à la précédente
+ i <- i + 4
+ if (i> 10) break
+}
> i
[1] 13
>
> i <- 1
> Repeat {# encore similaire
+ i <- i + 4
+ if (i> 10) break
+}
> i
[1] 13
Dans le premier extrait de code, la variable i a pris les valeurs 1, 5, 9 et 13 car la boucle a traversé ses itérations. A la valeur 13, la condition i <= 10 a échoué, et nous avons quitté la boucle.
Ce code montre trois manières différentes d'accomplir la même chose, la rupture jouant un rôle clé à la deuxième et à la troisième. Notez que repeat n'a pas de condition de sortie booléenne. Vous devez utiliser break (ou return ()). Une autre déclaration utile est next, qui indique de sautez le reste de l'itération actuelle de la boucle et passez directement à la suivante. Jetons un coup d'oeil à un exemple qui utilise next.
1 sim <- function(nreps) {
2 commdata <- list()
3 commdata$countabsamecomm <- 0
4 for (rep in 1:nreps) {
5 commdata$whosleft <- 1:20
6 commdata$numabchosen <- 0
7 commdata <- choosecomm(commdata,5)
8 if (commdata$numabchosen > 0) next
9 commdata <- choosecomm(commdata,4)
10 if (commdata$numabchosen > 0) next
11 commdata <- choosecomm(commdata,3)
12 }
13 print(commdata$countabsamecomm/nreps)
14 }
On retrouve les déclarations next dans les lignes 8 et 10. Voyons comment elles fonctionnent et comment ils améliorent les alternatives. Ces deux déclarations se produisent dans la boucle qui commence à la ligne 4. Ainsi, lorsque la condition if se maintient dans ligne 8, les lignes 9 à 11 seront ignorées et le contrôle sera transféré à la ligne 4.
La situation de la ligne 10 est similaire. Sans l'utilisation de next, nous devrions recourir à la déclaration if, quelque chose comme ceci:
1 sim <- function(nreps) {
2 commdata <- list()
3 commdata$countabsamecomm <- 0
4 for (rep in 1:nreps) {
5 commdata$whosleft <- 1:20
6 commdata$numabchosen <- 0
7 commdata <- choosecomm(commdata,5)
8 if (commdata$numabchosen == 0) {
9 commdata <- choosecomm(commdata,4)
10 if (commdata$numabchosen == 0)
11 commdata <- choosecomm(commdata,3)
12 }
13 }
14 print(commdata$countabsamecomm/nreps)
15 }
Cet exemple est simple et n’a que deux niveau. Cependant, les déclarations imbriquées peuvent devenir confuses lorsque vous avez plusieurs niveaux.
La déclaration for fonctionne sur n'importe quel vecteur, quel que soit le mode. Vous pouvez boucler sur un vecteur de noms de fichiers par exemple. Disons que nous avons un fichier nommé file1 avec les contenus suivants:
1
2
3
4
5
6
Nous avons également un fichier nommé file2 avec ces contenus:
5
12
13
La boucle suivante lit et imprime chacun de ces fichiers. Nous utilisons la fonction scan () pour lire dans un fichier de nombres et stocker ces valeurs dans un vecteur.
> for (fn in c("file1","file2")) print(scan(fn))
Read 6 items
[1]123456
Read 3 items
[1] 51213
Donc, fn est d'abord configuré dans file1, et ce fichier est lu et imprimé. Ensuite, la même chose arrive pour le file2.
7.1.2 Looping Over Nonvector Sets
R ne supporte pas directement l'itération sur les ensembles non vectoriels, mais il existe quelques moyens indirects et faciles à accomplir:
• Utilisez la fonction lapply (), en supposant que les itérations de la boucle sont indépendantes l'un de l'autre, ce qui leur permet d'être exécuté dans n'importe quel ordre.
• Utilisez la fonction get (). Comme son nom l'indique, cette fonction prend comme argument une chaîne de caractères représentant le nom de l'objet et retourne l'objet de ce nom. Cela semble simple, mais get () est une fonction très puissante.
Regardons un exemple d'utilisation de get (). Disons que nous avons deux matrices, u et v, contenant des données statistiques, et nous souhaitons appliquer la fonction de régression linéaire de R, lm () à chacun d'eux.
>u
[,1] [,2]
[1,] 1 1
[2,] 2 2
[3,] 3 4
>v
[,1] [,2]
[1,] 8 15
[2,] 12 10
[3,] 20 2
> for (m in c("u","v")) {
+ z <- get(m)
+ print(lm(z[,2] ~ z[,1]))
+}
Call:
lm(formula = z[, 2] ~ z[, 1])
Coefficients:
(Intercept) z[, 1]
-0.6667 1.5000
Call:
lm(formula = z[, 2] ~ z[, 1])
Coefficients:
(Intercept) z[, 1]
23.286 -1.071
Ici, m a été réglé pour vous. Ensuite, ces lignes attribuent la matrice u à z, qui permet l'appel de lm () sur u:
z <- get (m) imprimer (lm (z [, 2] ~ z [, 1]))
La même chose se produit alors avec v.
7.1.3 si et sinon
La syntaxe pour if-else (si et sinon) ressemble à ceci:
if (r == 4) {
x <- 1
} else {
x <- 3
y <- 4
}
Il semble simple, mais il y a une subtilité importante ici. La section if se compose d'une seule déclaration:
x <- 1
Donc vous devriez peut-être penser à tort que les entretoises autour de cette déclaration ne sont pas nécessaires. Une instruction if-else fonctionne comme un appel de fonction et, en tant que telle, elle renvoie la dernière valeur attribuée.
v <- if (condition) expression1 else expression2
Cela définira v pour le résultat de expression1 ou expression2, en fonction de if condition est vrai. Vous pouvez utiliser cela pour compacter votre code. Voici un exemple simple:
> x <- 2
> y <- if(x == 2) x else x+1
> y
[1] 2
> x <- 3
> y <- if(x == 2) x else x+1
> y
[1] 4
Sans prendre cette indication, le code y <- if (x == 2) x else x + 1 serait plutôt composé d'un peu plus encombré
if (x == 2) y <- x else y <- x + 1
Dans des exemples plus complexes, expression1 et / ou expression2 pourraient être appels de fonctions. D'autre part, vous ne devriez probablement pas laisser la compacité prenez la priorité sur la clarté.
Lorsque vous travaillez avec des vecteurs, utilisez la fonction ifelse (), comme indiqué dans chapitre 2, car il produira probablement un code plus rapide.