Rappelons l'exemple suivant du chapitre 2:
> X <- c (1,2,4)
> Noms (x)
NUL
> Noms (x) <- c ("a", "b", "ab")
> Noms (x)
[1] "a" "b" "ab"
> X
A b ab
1 2 4
Considérons une ligne en particulier:
> Noms (x) <- c ("a", "b", "ab")
As-tu totalement inoffensif, hein? Et bien non. En fait, c'est scandaleux! Comment
Terre peut-on attribuer une valeur au résultat d'un appel de fonction? La résolution
À cette étrange situation réside dans la notion R des fonctions de remplacement.
La ligne précédente du code R en fait est le résultat de l'exécution de la
Suivant:
X <- "noms <-" (x, valeur = c ("a", "b", "ab"))
Non, ce n'est pas une faute de frappe. L'appel ici est en effet à une fonction nommée
Noms <- (). (Nous devons insérer les guillemets en raison des caractères spéciaux
impliqué.)


7.10.1 Qu'est-ce qui est considéré comme une fonction de remplacement?
Toute instruction d'affectation dans laquelle le côté gauche n'est pas seulement un identifiant
(C'est-à-dire un nom de variable) est considéré comme une fonction de remplacement. Quand
Rencontrant ceci:
G (u) <- v
R essayera d'exécuter ceci:
U <- "g <-" (u, value = v)
Notez le "essai" dans la phrase précédente. La déclaration échouera si vous
N'ont pas défini précédemment g <- (). Notez que la fonction de remplacement a
Un argument de plus que la fonction d'origine g (), une valeur d'argument nommée,
Pour les raisons expliquées dans cette section.
Dans les chapitres précédents, vous avez vu cette déclaration innocente:
X [3] <- 8
Le côté gauche n'est pas un nom de variable, donc il doit s'agir d'une fonction de remplacement,
Et en effet c'est comme suit.
Les opérations de souscription sont des fonctions. La fonction "[" () est pour la lecture
Éléments vectoriels, et "[<-" () est utilisé pour écrire. Voici un exemple:
> X <- c (8,88,5,12,13)
> X
Structures de programmation R 183
Www

[1] 8 88 5 12 13
> X [3]
[1] 5
> "[" (X, 3)
[1] 5
> X <- "[<-" (x, 2: 3, valeur = 99: 100)
> X
[1] 8 99 100 12 13
Encore une fois, cet appel compliqué dans cette ligne:
> X <- "[<-" (x, 2: 3, valeur = 99: 100)
Effectue simplement ce qui se passe derrière les scènes lorsque nous exécutons ceci:
X [2: 3] <- 99: 100
Nous pouvons facilement vérifier ce qui se passe de la sorte:
> X <- c (8,88,5,12,13)
> X [2: 3] <- 99: 100
> X
[1] 8 99 100 12 13


7.10.2 Exemple étendu: une classe vectorielle auto-livre
Supposons que nous ayons des vecteurs sur lesquels nous devons suivre les écrits. En d'autre
Mots, lorsque nous exécutons ce qui suit:
X [2] <- 8
Nous souhaitons non seulement modifier la valeur dans x [2] à 8 mais aussi augmenter
Un nombre de fois x [2] a été écrit. Nous pouvons le faire par
Écriture de versions spécifiques aux classes des fonctions de remplacement génériques pour vecteur
Sous-scriptures.
REMARQUE Ce code utilise des classes, dont nous allons discuter en détail au chapitre 9. Pour l'instant, vous tous
Il faut savoir si les classes S3 sont construites en créant une liste puis en l'untissant
En classe en appelant la fonction class ().
1 # classe "bookvec" de vecteurs qui contiennent des écrits de leurs éléments
2
3 # chaque instance de la classe comprend une liste dont les composants sont les
4 valeurs vectorielles et un vecteur de dénombrements
5
6 # construire un nouvel objet de classe bookvec
7 newbookvec <- function (x) {
8 tmp <- list ()
9 tmp $ vec <- x # le vecteur lui-même
10 tmp $ wrts <- rep (0, longueur (x)) # comptes des écritures, un pour chaque élément
11 classe (tmp) <- "bookvec"
12 retour (tmp)
13}
14
15 # fonction à lire
16 "[.bookvec" <- function (bv, subs) {
17 retour (bv $ vec [subs])
18}
19
20 # fonction à écrire
21 "[<-. Bookvec" <- function (bv, subs, value) {
22 bv $ wrts [subs] <- bv $ wrts [subs] + 1 # note le recyclage
23 bv $ vec [subs] <- valeur
24 retour (bv)
25}
26 \ end {Code}
27
28 Testez-le.
29
30 \ begin {Code}
31> b <- newbookvec (c (3,4,5,5,12,13))
32> b
33 $ vec
34 [1] 3 4 5 5 12 13
35
36 $ pistes
37 [1] 0 0 0 0 0 0
38
39 attr (, "classe")
40 [1] "bookvec"
41> b [2]
42 [1] 4
43> b [2] <- 88 # essayez d'écrire
44> b [2] # a travaillé?
45 [1] 88
46> b $ wrts # nombre d'écriture incrémenté?
47 [1] 0 1 0 0 0 0
Nous avons nommé notre classe "bookvec", car ces vecteurs feront leur
La comptabilité propre, c'est-à-dire suivre les comptes d'écriture. Donc, les souscriptions
Les fonctions seront [.bookvec () et [<-. Bookvec ().

Notre fonction newbookvec () (ligne 7) fait la construction pour cette classe. Dans
Vous pouvez voir la structure de la classe: un objet sera constitué du vecteur
Lui-même, vec (ligne 9), et un vecteur de comptes d'écriture, des pistes (ligne 10).
Soit dit en passant, notez dans la ligne 11 que la classe de fonction () elle-même est un remplacement
fonction!
Les fonctions [.bookvec () et [<-. Bookvec () sont assez simples.
N'oubliez pas de retourner l'objet entier dans ce dernier.