R est un langage structuré en bloc comme C, C ++, Python, Perl, etc. Comme vous l'avez fait déjà vu, les blocs sont délimités par des accolades, bien que les accolades soient facultatives si le bloc se compose d'une simple déclaration. Les déclarations sont séparées par des caractères de nouvelle ligne ou par des points-virgules.
Dans cette partie, nous allons couvrir la structure de base de R en tant que langage de programmation. Nous allons passer en revue quelques détails supplémentaires sur les boucles, ensuite nous allons aller tout droit dans les fonctions, qui occuperont la majeure partie de cette partie.
Dans le chapitre 5, nous lisons dans un ensemble de données à partir d'un fichier nommé exams:
> testscores <- read.table ("exams", header = TRUE)
L'argument header = TRUE indique à R que nous avons une ligne d'en-tête, donc R devrait ne comptez pas cette première ligne dans le fichier en tant que donnée.
Ceci est un exemple de l'utilisation des arguments nommés. Voici les premiers lignes de la fonction:
> read.table
function (file, header = FALSE, sep = "", quote = "\"'", dec = ".",
row.names, col.names, as.is = !stringsAsFactors, na.strings = "NA",
colClasses = NA, nrows = -1, skip = 0, check.names = TRUE,
fill = !blank.lines.skip, strip.white = FALSE, blank.lines.skip = TRUE,
comment.char = "#", allowEscapes = FALSE, flush = FALSE,
stringsAsFactors = default.stringsAsFactors(), encoding = "unknown")
{
if (is.character(file)) {
file <- file(file, "r")
on.exit(close(file))
...
...
Le deuxième argument formel s'appelle header. Le champ FALSE signifie que cet argument est facultatif, et si nous ne le spécifions pas, la valeur par défaut sera FALSE. Si nous ne voulons pas la valeur par défaut, nous devons nommer l'argument dans notre appel:
> Testscores <- read.table ("examens", header = TRUE).
Le tableau suivant répertorie les opérateurs de base.
x + y Addition
x - y Soustraction
x * y Multiplication
x / y Division
x^y Exposant
x %% y Arithmétique modulaire
x% /% y Division entière
x == y Test pour l'égalité
x <= y Test pour inférieur ou égal à
x > = y Test supérieur ou égal à
x && y Booléen AND pour les scalaires
x || y Booléen OR pour les scalaires
x & y Booléen AND pour vecteurs (vecteur x, y)
x | y Booléen OR pour les vecteurs (vecteur x, y)
! x négation booléenne
Bien que R ostensiblement n'a pas de types scalaires, les scalaires étant traités comme vecteurs à un élément, on voit l'exception dans ce tableau qu’il existe différents les opérateurs booléens pour les scalaires et les cas vecteurs. Cela peut sembler étrange, mais un exemple simple démontrera la nécessité d'une telle distinction.
>x
[1] TRUE FALSE TRUE
>y
[1] TRUE TRUE FALSE
>x&y
[1] TRUE FALSE FALSE
> x[1] && y[1]
[1] TRUE
> x && y # regarde juste les premiers éléments de chaque vecteur
[1] TRUE
> if (x[1] && y[1]) print("both TRUE")
[1] "both TRUE"
> if (x & y) print("both TRUE")
[1] "both TRUE"
Warning message:
In if (x & y) print("both TRUE") :
La condition a une longueur> 1 et seul le premier élément sera utilisé. Le point central est que, lors de l'évaluation d'un if, nous avons besoin d'un seul booléen, et non un vecteur de booléens, d'où l'avertissement vu dans l'exemple précédent, ainsi que la nécessité d'avoir à la fois les opérateurs et &&.
Les valeurs booléennes TRUE et FALSE peuvent être abrégées en T et F (Les deux doivent être mis en majuscules). Ces valeurs changent pour 1 et 0 en arithmétique expressions:
> 1 < 2
[1] TRUE
> (1 < 2) * (3 < 4)
[1] 1
> (1 < 2) * (3 < 4) * (5 < 1)
[1] 0
> (1 < 2) == TRUE
[1] TRUE
> (1 < 2) == 1
[1] TRUE
Dans le deuxième calcul, par exemple, la comparaison 1 <2 retourne TRUE, et 3 <4 rend TRUE aussi. Les deux valeurs sont traitées comme 1 valeurs, donc le
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.
R est un langage structuré en bloc comme C, C ++, Python, Perl, etc. Comme vous l'avez fait déjà vu, les blocs sont délimités par des accolades, bien que les accolades soient facultatives si le bloc se compose d'une simple déclaration. Les déclarations sont séparées par des caractères de nouvelle ligne ou par des points-virgules.
Dans cette partie, nous allons couvrir la structure de base de R en tant que langage de programmation. Nous allons passer en revue quelques détails supplémentaires sur les boucles, ensuite nous allons aller tout droit dans les fonctions, qui occuperont la majeure partie de cette partie.