En complément de la réponse acceptée, j'aimerais noter que les fonctions de remplacement peuvent être définies également pour des fonctions non standard, à savoir les opérateurs (cf. ?Syntax
) et des constructions de flux de contrôle. (voir ?Control
).
Notez également qu'il est parfaitement acceptable de concevoir un générique et des méthodes associées pour les fonctions de remplacement.
opérateurs
Lors de la définition d'une nouvelle classe, il est courant de définir des méthodes S3 pour les éléments suivants $<-
, [[<-
et [<-
Voici quelques exemples data.table:::`$<-.data.table`
, data.table:::`[<-.data.table`
ou tibble:::`$.tbl_df`
.
Cependant pour tout autre opérateur nous pouvons écrire une fonction de remplacement, quelques exemples :
`!<-` <- function(x, value) !value
x <- NULL # x needs to exist before replacement functions are used!
!x <- TRUE
x
#> [1] FALSE
`==<-` <- function(e1, e2, value) replace(e1, e1 == e2, value)
x <- 1:3
x == 2 <- 200
x
#> [1] 1 200 3
`(<-` <- function(x, value) sapply(x, value, USE.NAMES = FALSE)
x <- c("foo", "bar")
(x) <- toupper
x
#> [1] "FOO" "BAR"
`%chrtr%<-` <- function(e1, e2, value) {
chartr(e2, value, e1)
}
x <- "woot"
x %chrtr% "o" <- "a"
x
#> [1] "waat"
nous pouvons même définir <-<-
mais l'analyseur syntaxique empêchera son utilisation si nous appelons x <- y <- z
Nous devons donc utiliser le symbole d'affectation de gauche à droite.
`<-<-` <- function(e1, e2, value){
paste(e2, e1, value)
}
x <- "b"
"a" -> x <- "c"
x
#> [1] "a b c"
Fait amusant, <<-
peut avoir un double rôle
x <- 1:3
x < 2 <- NA # this fails but `<<-` was called!
#> Error in x < 2 <- NA: incorrect number of arguments to "<<-"
# ok let's define it then!
`<<-` <- function(x, y, value){
if (missing(value)) {
eval.parent(substitute(.Primitive("<<-")(x, y)))
} else {
replace(x, x < y, value)
}
}
x < 2 <- NA
x
#> [1] NA 2 3
x <<- "still works"
x
#> [1] "still works"
les constructions de flux de contrôle
En pratique, on les rencontre rarement (en fait, je suis responsable de la seule utilisation pratique que je connaisse, dans la définition de l for<-
pour mon paquet pbfor ), mais R est assez souple, ou assez fou, pour nous permettre de les définir. Cependant, pour les utiliser réellement, en raison de la manière dont les constructions de flux de contrôle sont analysées, nous devons utiliser l'affectation de gauche à droite. ->
.
`repeat<-` <- function(x, value) replicate(value, x)
x <- "foo"
3 -> repeat x
x
#> [1] "foo" "foo" "foo"
function<-
function<-
peut être défini en principe mais, à ma connaissance, on ne peut rien en faire.
`function<-` <- function(x,value){NULL}
3 -> function(arg) {}
#> Error in function(arg) {: target of assignment expands to non-language object
6 votes
Il s'agit d'un Q parfaitement acceptable pour le SO
2 votes
Duplicata possible de
levels<-
( Quelle est cette sorcellerie ?0 votes
Voir Prolonger R.- John Chambers (2016) : page 73 à 79 du chapitre 5