Quelles sont les différences entre les opérateurs d'affectation =
et <-
dans R?
Comme le montre votre exemple, =
et <-
ont une priorité d'opérateur légèrement différente (qui détermine l'ordre d'évaluation lorsqu'ils sont mélangés dans la même expression). En fait, ?Syntax
dans R donne la table de priorité d'opérateur suivante, du plus haut au plus bas:
…
‘-> ->>’ rightwards assignment
‘<- <<-’ assignment (right to left)
‘=’ assignment (right to left)
…
Mais est-ce la seule différence?
Puisque vous posiez des questions sur les opérateurs d'affectation : oui, c'est la seule différence. Cependant, vous seriez pardonné de croire le contraire. Même la documentation R ?assignOps
affirme qu'il y a plus de différences:
L'opérateur <-
peut être utilisé n'importe où, alors qu'il =
n'est autorisé qu'au niveau supérieur (par exemple, dans l'expression complète tapée à l'invite de commande) ou comme l'une des sous-expressions dans une liste d'expressions contreventée.
Ne précisons pas trop: la documentation R est (subtilement) fausse [ 1 ] . C'est facile à montrer: il suffit de trouver un contre-exemple de l' =
opérateur qui n'est pas (a) au niveau supérieur, ni (b) une sous-expression dans une liste d'expressions contreventée (ie {…; …}
). - Sans plus tarder:
x
# Error: object 'x' not found
sum((x = 1), 2)
# [1] 3
x
# [1] 1
De toute évidence, nous avons effectué une affectation, en utilisant =
, en dehors des contextes (a) et (b). Alors, pourquoi la documentation d'une fonctionnalité de base du langage R est-elle erronée depuis des décennies?
C'est parce que dans la syntaxe de R, le symbole =
a deux significations distinctes qui sont systématiquement confondues:
- La première signification est en tant qu'opérateur d'affectation . C'est tout ce dont nous avons parlé jusqu'à présent.
- La deuxième signification n'est pas un opérateur mais plutôt un jeton de syntaxe qui signale un argument nommé passant dans un appel de fonction. Contrairement à l'
=
opérateur, il n'exécute aucune action au moment de l'exécution, il modifie simplement la façon dont une expression est analysée.
Voyons voir.
Dans n'importe quel morceau de code de la forme générale…
‹function_name›(‹argname› = ‹value›, …)
‹function_name›(‹args›, ‹argname› = ‹value›, …)
… Le =
est le jeton qui définit le passage d'argument nommé: ce n'est pas l'opérateur d'affectation. De plus, =
est totalement interdit dans certains contextes syntaxiques:
if (‹var› = ‹value›) …
while (‹var› = ‹value›) …
for (‹var› = ‹value› in ‹value2›) …
for (‹var1› in ‹var2› = ‹value›) …
N'importe lequel de ces éléments générera une erreur «inattendu '=' dans ‹bla›».
Dans tout autre contexte, =
fait référence à l'appel d'opérateur d'affectation. En particulier, le simple fait de mettre des parenthèses autour de la sous-expression rend tout ce qui précède (a) valide et (b) une affectation . Par exemple, ce qui suit effectue l'affectation:
median((x = 1 : 10))
Mais aussi:
if (! (nf = length(from))) return()
Maintenant, vous pourriez objecter qu'un tel code est atroce (et vous avez peut-être raison). Mais j'ai pris ce code de la base::file.copy
fonction (en le remplaçant <-
par =
) - c'est un modèle omniprésent dans une grande partie de la base de code R principale.
L' explication originale de John Chambers , sur laquelle la documentation R est probablement basée, explique en fait cela correctement:
[ =
affectation] n'est autorisée qu'à deux endroits de la grammaire: au niveau supérieur (en tant que programme complet ou expression saisie par l'utilisateur); et lorsqu'ils sont isolés de la structure logique environnante, par des accolades ou une paire supplémentaire de parenthèses.
Une confession: j'ai menti plus tôt. Il existe une différence supplémentaire entre les opérateurs =
et <-
: ils appellent des fonctions distinctes. Par défaut, ces fonctions font la même chose mais vous pouvez les remplacer séparément pour changer le comportement. En revanche, <-
et ->
(affectation de gauche à droite), bien que syntaxiquement distincts, appellent toujours la même fonction. Remplacer l'un remplace également l'autre. Le savoir est rarement pratique, mais il peut être utilisé pour des manigances amusantes .
<-
symbole proviennent d'anciens claviers APL qui avaient en fait une seule<-
clé.