¿Cuáles son las diferencias entre “=” y “<-” operadores de asignación de R?

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

  •  20-09-2019
  •  | 
  •  

Pregunta

¿Cuáles son las diferencias entre el = operadores de asignación y <- en R?

Sé que los operadores son ligeramente diferentes, como muestra este ejemplo

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

Pero es esta la única diferencia?

¿Fue útil?

Solución

  

¿Cuáles son las diferencias entre el = operadores de asignación y <- en R?

A medida que su ejemplo muestra, = y <- tienen ligeramente diferente precedencia de operador (que determina el orden de evaluación cuando se mezclan en la misma expresión). De hecho, ?Syntax en R da la siguiente prioridad de los operadores mesa, de mayor a menor:

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

Pero es esta la única diferencia?

Desde que estabas preguntando acerca de los operadores de asignación : Sí, esa es la única diferencia. Sin embargo, sería comprensible para creer lo contrario. Incluso la documentación de R ?assignOps afirma que hay más diferencias:

  

El <- operador puede utilizar en cualquier lugar,   mientras que el = operador sólo se permite en el nivel superior (por ejemplo,   en la expresión completa se escriba en el símbolo del sistema) o como una   de las subexpresiones en una lista arriostrados de expresiones.

No pongamos un punto demasiado fino en él: la documentación R es (sutilmente) mal [ 1 ] . Esto es fácil de demostrar: sólo tenemos que encontrar un contraejemplo del operador = que no es (a) en el nivel superior, ni (b) una subexpresión en una lista de expresiones arriostrados (es decir {…; …}). - Sin más preámbulos:

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

Es evidente que hemos realizado una asignación, usando =, fuera de contextos (a) y (b). Así que, ¿por qué tiene la documentación de un elemento central R lenguaje equivocado durante décadas?

Se debe a que en la sintaxis de R el símbolo = tiene dos significados distintos que consiguen confunden rutinariamente:

  1. El primer significado es como un operador de asignación . Esto es todo lo que hemos hablado hasta ahora.
  2. El segundo significado no es un operador, sino más bien un Moneda sintaxis que las señales de llamado argumento que pasa en una llamada de función. A diferencia del operador = no realiza ninguna acción en tiempo de ejecución, simplemente cambia la forma en que se analiza una expresión.

Vamos a ver.

En cualquier parte del código de la forma general ...

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

... = es la señal que define el paso de argumentos con nombre: es no el operador de asignación. Por otra parte, es totalmente = prohibido en algunos contextos sintácticos:

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

Cualquiera de estos elevar un error “inesperado '=' en ”.

En cualquier otro contexto, = se refiere a la llamada operador de asignación. En particular, simplemente poniendo paréntesis alrededor de la subexpresión hace cualquiera de los anteriores (a) válido, y (b) un asignación . Por ejemplo, la siguiente realiza asignación:

median((x = 1 : 10))

Pero también:

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

Ahora se podría objetar que dicho código es atroz (y puede que tengas razón). Pero tomé el código de la función base::file.copy (reemplazando <- con =) -. Es un patrón generalizado en gran parte del código base del núcleo de I

El explicación original de John Chambers , que la documentación de la R se basa probablemente en , en realidad explica esto correctamente:

  

[asignación = IS] permitido en sólo dos lugares en la gramática: en el nivel superior (como un programa completo o expresión-tecleado por el usuario); y cuando se aíslan de sus alrededores estru lógicomagen, mediante abrazaderas o un par extra de paréntesis.


Una confesión: he mentido antes. Hay es una diferencia adicional entre los operadores y = <-: ellos llaman funciones distintas. Por defecto estas funciones hacen lo mismo pero se puede reemplazar cualquiera de ellos por separado para cambiar el comportamiento. Por el contrario, <- y -> (asignación de izquierda a derecha), aunque sintácticamente distinto, siempre llamar a la mismo función. Anulando también se anula la otra. Saber esto es raramente práctica pero puede usarse para algunos travesuras divertidas .

Otros consejos

La diferencia de los operadores de asignación es más clara cuando se utilizan para establecer una valor del argumento en una llamada de función. Por ejemplo:

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

En este caso, x se declara dentro del alcance de la función, por lo que no existe en el espacio de trabajo del usuario.

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

En este caso, x se declara en el espacio de trabajo del usuario, por lo que se puede utilizar después de la llamada a la función se ha completado.


Hay una preferencia general entre la comunidad de R para el uso de <- para la asignación (aparte de en las firmas de función) para la compatibilidad con (muy) viejas versiones de S-Plus. Tenga en cuenta que los espacios ayudan a aclarar situaciones como

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

La mayoría de los entornos de desarrollo de I tienen atajos de teclado para hacer <- más fácil de escribir. Ctrl + = en Arquitecto, Alt + - en rstudio ( Opción + < kbd> - bajo macOS), Shift + -. (subrayado) en emacs + ESS


Si prefiere escribir = a <- pero desea utilizar el símbolo de asignación más común para el código publicado públicamente (en CRAN, por ejemplo), entonces usted puede utilizar una de las funciones tidy_* en el paquete formatR para reemplazar automáticamente = con <-.

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

La respuesta a la pregunta "¿Por qué x <- y = 5 lanzar un error pero no x <- y <- 5?" es "hay que bajar a la magia contenida en el programa de análisis". sintaxis de R contiene muchos casos ambiguos que tienen que ser resueltos de una manera u otra. El analizador elige para resolver los bits de la expresión en diferentes órdenes en función de si se utilizó = o <-.

Para entender lo que está pasando, lo que necesita saber que la asignación vuelve en silencio el valor que se le asigna. Se puede ver que con mayor claridad mediante la impresión de forma explícita, por ejemplo print(x <- 2 + 3).

En segundo lugar, es más clara si utilizamos notación de prefijo para la asignación. Así

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

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

El analizador interpreta x <- y <- 5 como

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

Podríamos esperar que x <- y = 5 sería entonces

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

pero en realidad se interpreta como

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

Esto es porque = es menor precedencia que <-, como se muestra en la ?Syntax página de ayuda.

Libro de estilo R de Google simplifica el problema mediante la prohibición de la asignación "=" para. No es una mala elección.

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

El manual R entra en detalle agradable en los 5 operadores de asignación.

http: //stat.ethz. ch / R-manual / R-patched / biblioteca / base / html / assignOps.html

x = y = 5 es equivalente a x = (y = 5), debido a que la operadores de asignación "grupo" de derecha a izquierda, la cual trabaja. Significado: asignar a 5 y, dejando el número 5; y luego asignar ese 5 a x.

Esto no es lo mismo que (x = y) = 5, que no funciona! Significado: asignar el valor de y a x, dejando el valor de y; y luego asignar a 5, umm ..., ¿qué es exactamente?

Cuando se mezclan los diferentes tipos de operadores de asignación, <- une más apretado que =. Así x = y <- 5 se interpreta como x = (y <- 5), que es el caso que tenga sentido.

Por desgracia, x <- y = 5 se interpreta como (x <- y) = 5, que es el caso que no funciona!

Ver ?Syntax y ?assignOps para la precedencia (de unión) y la agrupación de reglas.

De acuerdo con John Chambers, el operador = sólo se permite al "más alto nivel", lo que significa que no está permitido en las estructuras de control como if, haciendo ilegal el siguiente error de programación.

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

A medida que escribe, "No permitir la nueva forma de asignación [=] en expresiones de control evita errores de programación (tales como el ejemplo anterior) que son más probables con el operador igual que con otros S asignaciones."

Puede llegar a hacer esto si está "aislado de estructura lógica que rodea, por llaves o un par extra de paréntesis," por lo if ((x = 0)) 1 else x funcionaría.

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

El <- operadores y = asignan en el medio ambiente en el que se evalúan. El <- operador puede utilizar en cualquier lugar, mientras que el = operador sólo se permite en el nivel superior (por ejemplo, en la expresión completa se escriba en el símbolo del sistema) o como uno de las subexpresiones en una lista de expresiones arriostrados.

Esto también puede añadir a la comprensión de la diferencia entre esos dos operadores:

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

Para el primer elemento R ha asignado valores y nombre propio, mientras que el nombre del segundo elemento parece un poco extraño.

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 versión 3.3.2 (31/10/2016); macOS Sierra 10.12.1

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top