Quelles sont les différences entre « = » et « <- » opérateurs d'affectation en R?

StackOverflow https://stackoverflow.com/questions/1741820

  •  20-09-2019
  •  | 
  •  

Question

Quelles sont les différences entre les opérateurs d'affectation = et <- en R?

Je sais que les opérateurs sont légèrement différents, comme le montre cet exemple

x <- y <- 5
x = y = 5
x = y <- 5
x <- y = 5
# Error in (x <- y) = 5 : could not find function "<-<-"

Mais est-ce la seule différence?

Était-ce utile?

La solution

  

Quelles sont les différences entre les opérateurs d'affectation = et <- en R?

En tant que votre exemple montre, = et <- ont opérateur légèrement différente priorité (qui détermine l'ordre d'évaluation quand ils sont mélangés dans la même expression). En fait, ?Syntax R donne la priorité de l'opérateur suivant table, 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 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 ya plus différences:

  

Le <- opérateur peut être utilisé partout,   tandis que le = de l'opérateur est autorisé uniquement au niveau supérieur (par exemple,   dans l'expression complète tapé à l'invite de commande) ou un   des sous-expressions dans une liste contreventement des expressions.

Il ne faut pas mettre trop insister là-dessus: la documentation R est (subtilement) mal [ 1 ] . Cela est facile à montrer: nous avons juste besoin 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 contreventement des expressions (à savoir {…; …}). - Sans plus tarder:

x
# Error: object 'x' not found
sum((x = 1), 2)
# [1] 3
x
# [1] 1

Il est clair que nous avons effectué une mission, en utilisant =, en dehors des contextes (a) et (b). Alors, pourquoi la documentation d'une fonctionnalité de langage R core eu tort pendant des décennies?

Il est parce que dans la syntaxe de R le = symbole a deux significations distinctes qui reçoivent systématiquement: confondait

  1. Le premier sens est comme un opérateur d'affectation . C'est tout ce que nous avons parlé jusqu'à présent.
  2. La deuxième signification est pas un opérateur mais plutôt un jeton de syntaxe que les signaux argument nommé passant dans un appel de fonction. Contrairement à l'opérateur = il effectue aucune action lors de l'exécution, il change simplement la façon dont une expression est analysée.

Voyons voir.

En tout morceau de code de la forme générale ...

‹function_name›(‹argname› = ‹value›, …)
‹function_name›(‹args›, ‹argname› = ‹value›, …)

... = est le jeton qui définit argument nommé qui passe: il est pas l'opérateur d'affectation. De plus, = est tout à fait interdit dans certains contextes syntaxiques:

if (‹var› = ‹value›) …
while (‹var› = ‹value›) …
for (‹var› = ‹value› in ‹value2›) …
for (‹var1› in ‹var2› = ‹value›) …

Tous ces éléments vont générer une erreur « inattendu '=' dans ».

Dans tout autre contexte, = fait référence à l'appel de l'opérateur d'affectation. En particulier, en mettant entre parenthèses simplement autour de la sous-expression fait tout de ce qui précède (a) valide, et (b) une affectation . Par exemple, ce qui suit effectue la cession:

median((x = 1 : 10))

Mais aussi:

if (! (nf = length(from))) return()

Maintenant, vous pourriez objecter que tel code est atroce (et vous pouvez être à droite). Je pris le code de la fonction de base::file.copy (remplaçant <- avec =) -. Il est un motif omniprésent dans une grande partie du noyau R codebase

originale par John Chambers qui la la documentation R est probablement basée sur , explique en fait cela correctement:

  

[affectation de = est] admis dans deux endroits dans la grammaire: au niveau supérieur (comme un programme complet ou l'expression tapé par l'utilisateur); et lorsqu'il est isolé à partir de stru logique environnantecture, par des entretoises ou une paire de parenthèses.


Une confession: je mentais plus tôt. Il une différence supplémentaire entre les opérateurs de = et <-: ils appellent des fonctions distinctes. Par défaut, ces fonctions font la même chose, mais vous pouvez remplacer l'un d'eux séparément pour modifier le comportement. En revanche, <- et -> (affectation de gauche à droite), bien que syntaxiquement distincte, toujours faire appel à la même fonction. Redéfinition remplace également l'un de l'autre. Sachant cela est rarement pratique mais peut être utilisés pour certains manigances fun .

Autres conseils

La différence dans les opérateurs d'affectation de est plus clair lorsque vous les utilisez pour définir une la valeur d'argument dans un appel de fonction. Par exemple:

median(x = 1:10)
x   
## Error: object 'x' not found

Dans ce cas, x est déclaré dans le cadre de la fonction, il n'existe pas dans l'espace de travail de l'utilisateur.

median(x <- 1:10)
x    
## [1]  1  2  3  4  5  6  7  8  9 10

Dans ce cas, x est déclarée dans l'espace de travail de l'utilisateur, de sorte que vous pouvez l'utiliser après l'appel de fonction est terminée.


Il y a une préférence générale au sein de la communauté R pour l'utilisation <- pour l'attribution (autres que dans les signatures de fonction) pour la compatibilité avec les (très) anciennes versions de S-Plus. Notez que les espaces permettent de clarifier des situations comme

x<-3
# Does this mean assignment?
x <- 3
# Or less than?
x < -3

La plupart des R IDEs ont des raccourcis clavier pour rendre plus facile à taper <-. Ctrl + = Architect, Alt + - dans rstudio ( Option + < KBD> - sous MacOS), Maj + -. (souligné) dans emacs + ESS


Si vous préférez écrire = à <- mais souhaitez utiliser le symbole d'affectation plus commune pour le code rendu public (le CRAN, par exemple), vous pouvez utiliser l'un des fonctions tidy_* dans le package formatR pour remplacer automatiquement = avec <-.

library(formatR)
tidy_source(text = "x=1:5", arrow = TRUE)
## x <- 1:5

La réponse à la question « Pourquoi x <- y = 5 jeter une erreur, mais pas x <- y <- 5? » est «C'est vers le bas à la magie contenue dans l'analyseur ». La syntaxe de R contient ?Syntax page d'aide.

guide de style R Google simplifie la question en interdisant la cession pour « = ». Pas un mauvais choix.

https://google.github.io/styleguide/Rguide.xml

Le manuel R passe en détail agréable sur les 5 opérateurs d'affectation.

http: //stat.ethz. ch / R-manuel / R-patched / bibliothèque / base / html / assignOps.html

x = y = 5 est équivalent à x = (y = 5), parce que les opérateurs d'affectation « groupe » de droite à gauche, ce qui fonctionne. Signification: affecter 5 à y, en laissant le numéro 5; puis attribuez-lui que 5 à x.

Ce n'est pas la même chose que (x = y) = 5, qui ne fonctionne pas! Signification: assigner la valeur de y à x, en laissant la valeur de y; puis attribuez-lui 5 à, euh ..., qu'est-ce exactement?

Lorsque vous mélangez les différents types d'opérateurs d'affectation, <- lie plus serré que =. Donc x = y <- 5 est interprété comme x = (y <- 5), ce qui est le cas qui fait sens.

Malheureusement, x <- y = 5 est interprété comme (x <- y) = 5, ce qui est le cas qui ne fonctionne pas!

Voir ?Syntax et ?assignOps pour la priorité (contraignante) et les règles de groupement.

Selon John Chambers, le = opérateur est autorisé seulement à « niveau supérieur », ce qui signifie qu'il est interdit dans les structures de contrôle comme if, ce qui rend l'erreur de programmation suivante illégale.

> if(x = 0) 1 else x
Error: syntax error

Comme il l'écrit, « refuse la nouvelle forme d'affectation [=] dans les expressions de contrôle évite les erreurs de programmation (comme l'exemple ci-dessus) qui sont plus susceptibles de l'opérateur égal qu'avec d'autres missions de. »

Vous parvenez à le faire si elle est « isolé de la structure logique entourant, par des accolades ou une paire de parenthèses, » si if ((x = 0)) 1 else x fonctionnerait.

Voir http://developer.r-project.org/equalAssign.html

Les opérateurs <- et = dans l'environnement assignent dans lequel ils sont évalués. Le <- opérateur peut être utilisé partout, alors que l'opérateur = n'est autorisé au niveau supérieur (par exemple, dans l'expression complète tapé à l'invite de commande) ou comme l'un des les sous-expressions dans une liste contreventement des expressions.

Cela peut également ajouter à la compréhension de la différence entre ces deux opérateurs:

df <- data.frame(
      a = rnorm(10),
      b <- rnorm(10)
)

Pour le premier élément R a attribué des valeurs et nom propre, tandis que le nom du second élément semble un peu étrange.

str(df)
# 'data.frame': 10 obs. of  2 variables:
#  $ a             : num  0.6393 1.125 -1.2514 0.0729 -1.3292 ...
#  $ b....rnorm.10.: num  0.2485 0.0391 -1.6532 -0.3366 1.1951 ...

version R 3.3.2 (31/10/2016); macOS Sierra 10.12.1

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top