Domanda

Quali sono le differenze tra gli operatori di assegnazione = e <- in R?

Lo so che gli operatori sono leggermente diverse, come mostra questo esempio

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

Ma è questa l'unica differenza?

È stato utile?

Soluzione

  

Quali sono le differenze tra gli operatori di assegnazione = e <- in R?

Come vostro esempio mostra, = e <- hanno leggermente differente precedenza degli operatori (che determina l'ordine di valutazione quando sono miscelati nella stessa espressione). Infatti, ?Syntax in R pronunciato la seguente precedenza degli operatori tavolo, dal più alto al più basso:

…
‘-> ->>’           rightwards assignment
‘<- <<-’           assignment (right to left)
‘=’                assignment (right to left)
…

Ma è questa l'unica differenza?

Dal momento che stavi chiedendo circa le operatori di assegnazione : sì, che è l'unica differenza. Tuttavia, si sarebbe perdonato per credere altrimenti. Anche la documentazione R di ?assignOps sostiene che ci sono più differenze:

  

Il <- operatore può essere utilizzato ovunque,   mentre il = operatore è consentito solo al livello superiore (ad esempio,   nell'espressione completa digitato al prompt dei comandi) oppure come uno   delle sottoespressioni in un elenco di espressioni rinforzato.

Cerchiamo di non mettere troppo fine un punto su di esso: la documentazione R è (leggermente) sbagliato [ 1 ] . Questo è facile da mostrare: abbiamo solo bisogno di trovare un contro-esempio dell'operatore = che non è (a) al livello superiore, né (b) una sottoespressione in un elenco di espressioni rinforzato (vale a dire {…; …}). - Senza ulteriori indugi:

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

Chiaramente abbiamo effettuato un incarico, utilizzando =, al di fuori dei contesti (a) e (b). Quindi, perché ha la documentazione di una caratteristica fondamentale di lingua R sbagliato per decenni?

E 'perché nella sintassi di R il = simbolo ha due significati distinti che vengono abitualmente conflated:

  1. Il primo significato è come operatore di assegnazione . Questo è tutto ciò di cui abbiamo parlato finora.
  2. Il secondo significato non è un operatore, ma piuttosto una sintassi gettone che segnali denominato argomento passa in una chiamata di funzione. Diversamente l'operatore = svolge alcuna azione in fase di esecuzione, si limita cambia il modo espressione viene analizzata.

Vediamo.

In ogni pezzo di codice della forma generale ...

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

... = è il segno che definisce il nome di passaggio argomentazione: è non l'operatore di assegnazione. Inoltre, è del tutto = vietato , in alcuni contesti sintattici:

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

Uno di questi genererà un errore “imprevisto '=' in ”.

In qualsiasi altro contesto, = riferisce alla chiamata operatore di assegnazione. In particolare, semplicemente mettendo tra parentesi sottoespressione rende qualsiasi dei suddetti (a) valido, e (b) un assegnazione . Per esempio, il seguente esegue assegnazione:

median((x = 1 : 10))

Ma anche:

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

Ora si potrebbe obiettare che tale codice è atroce (e si può essere a destra). Ma ho preso questo codice dalla funzione base::file.copy (sostituendo <- con =) -. È un modello pervasivo in gran parte del codice di base di base di R

Il spiegazione originale da John Chambers , che la documentazione della R è probabilmente basato su , spiega in realtà questo correttamente:

  

[Assegnazione = è] consentito solo in due posti nella grammatica: al livello superiore (come un programma completo o un'espressione user-typed); e quando isolato dal circostante stru logicocture, da parentesi graffe o un paio di parentesi.


Una confessione: ho mentito in precedenza. Ci è una differenza ulteriore tra gli operatori = e <-: chiamano funzioni distinte. Per impostazione predefinita, queste funzioni fanno la stessa cosa, ma si possono ignorare uno di essi separatamente per modificare il comportamento. Per contro, <- e -> (assegnazione da sinistra a destra), anche se sintatticamente distinta, chiamare sempre il stesso funzione. Come ignorare uno ignora anche l'altra. Sapendo questo è ma possono essere usato per un po ' imbrogli divertimento .

Altri suggerimenti

La differenza di operatori di assegnazione è più chiaro quando li si utilizza per impostare un valore di argomento in una chiamata di funzione. Ad esempio:

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

In questo caso, x è dichiarata nell'ambito della funzione, quindi non esiste nell'area di lavoro dell'utente.

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

In questo caso, x è dichiarato nello spazio di lavoro dell'utente, in modo da poter utilizzare dopo la chiamata di funzione è stata completata.


C'è una preferenza generale tra la comunità R per l'utilizzo di <- per l'assegnazione (se non in funzione di firme) per la compatibilità con (molto) le vecchie versioni di S-Plus. Si noti che gli spazi contribuiscono a chiarire situazioni come

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

La maggior parte dei IDE R hanno le scorciatoie da tastiera per rendere <- più facile da digitare. Ctrl + = in Architect, Alt + - in RStudio ( Option + < kbd> - sotto MacOS), Maiusc + -. (sottolineatura) in emacs + ESS


Se si preferisce la scrittura a = <- ma si desidera utilizzare il simbolo di assegnazione più comune per il codice rilasciato pubblicamente (il CRAN, per esempio), allora si può utilizzare uno dei funzioni tidy_* nel pacchetto formatR per sostituire automaticamente = con <-.

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

La risposta alla domanda "Perché x <- y = 5 genera un errore, ma non x <- y <- 5?" è "E 'verso la magia contenuta nel parser". la sintassi di R contiene molti casi ambigui che devono essere risolti in un modo o nell'altro. Il parser sceglie di risolvere i bit della espressione in ordini differenti a seconda che è stato utilizzato = o <-.

Per capire cosa sta succedendo, è necessario sapere che l'assegnazione ritorna silenziosamente il valore che è stato assegnato. Si può vedere che più chiaramente esplicitamente la stampa, ad esempio print(x <- 2 + 3).

In secondo luogo, è più chiaro se si usa la notazione del prefisso per l'assegnazione. Quindi

x <- 5
`<-`(x, 5)  #same thing

y = 5
`=`(y, 5)   #also the same thing

Il parser interpreta x <- y <- 5 come

`<-`(x, `<-`(y, 5))

Ci si potrebbe aspettare che x <- y = 5 sarebbe allora

`<-`(x, `=`(y, 5))

, ma in realtà esso viene interpretato come

`=`(`<-`(x, y), 5)

Questo perché = è precedenza inferiore <-, come mostrato nella ?Syntax pagina di aiuto.

guida di stile R di Google semplifica il problema vietando il "=" per l'assegnazione. Non una cattiva scelta.

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

Il manuale R va in bel dettaglio su tutti i 5 operatori di assegnazione.

http: //stat.ethz. ch / R-manuale / R-patched / library / base / html / assignOps.html

x = y = 5 è equivalente a x = (y = 5), perché gli operatori di assegnazione "gruppo" da destra a sinistra, che funziona. Significato: assegnare a 5 y, lasciando il numero 5; e quindi assegnare tale 5 a x.

Questa non è la stessa di (x = y) = 5, che non funziona! Significato: assegnare il valore di y a x, lasciando il valore di y; e quindi assegnare 5 a, umm ..., che cosa esattamente?

Quando si mescolano i diversi tipi di operatori di assegnazione, <- si lega più stretto di =. Così x = y <- 5 viene interpretato come x = (y <- 5), che è il caso che abbia un senso.

Purtroppo, x <- y = 5 viene interpretato come (x <- y) = 5, che è il caso che non funziona!

Vedere ?Syntax e ?assignOps per la precedenza (vincolante) e il raggruppamento regole.

Secondo John Chambers, il = operatore è consentito solo al "livello superiore", il che significa che non è consentito in strutture di controllo come if, rendendo il seguente errore di programmazione illegale.

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

Come egli scrive, "Impedire la nuova forma di assegnazione [=] nelle espressioni di controllo evita errori di programmazione (come nell'esempio precedente) che hanno maggiori probabilità con l'operatore uguale rispetto ad altri incarichi S".

È possibile riuscire a fare questo se è "isolato dal circostante struttura logica, da parentesi graffe o un paio di parentesi", così if ((x = 0)) 1 else x avrebbe funzionato.

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

Gli operatori <- e = assegnare nell'ambiente in cui vengono valutati. Il <- operatore può essere utilizzato ovunque, mentre il = operatore è consentito solo al livello superiore (ad esempio, nell'espressione completo digitato al richiamo di ordine) o come uno degli le sottoespressioni in un elenco di espressioni rinforzato.

Questo può anche aggiungere alla comprensione della differenza tra questi due operatori:

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

Per il primo elemento R ha assegnato valori e nome proprio, mentre il nome del secondo elemento sembra un po 'strano.

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 ...

R versione 3.3.2 (2016/10/31); MacOS Sierra 10.12.1

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top