Pregunta ¿Cuáles son las diferencias entre "=" y "<-" en R?


¿Cuáles son las diferencias entre los 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 esta es la única diferencia?


540
2017-11-16 12:14


origen


Respuestas:


La diferencia en Operadores de Asignación es más claro cuando los usa para establecer un valor de argumento en una llamada a 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 puede usarlo después de que se haya completado la llamada a la función.


Hay una preferencia general entre la comunidad R por usar <- para la asignación (que no sea en las firmas de funciones) de compatibilidad con (muy) versiones antiguas 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 R IDE tienen atajos de teclado para hacer <- más fácil de escribir. Ctrl + = en Arquitecto, Alt + - en RStudio (Opción + - bajo macOS), Cambio + - (guion bajo) en emacs + ESS.


Si prefieres escribir = a <- pero desea utilizar el símbolo de asignación más común para el código de publicación pública (en CRAN, por ejemplo), entonces puede usar uno de los tidy_* funciones en el formatR paquete 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" depende de la magia contenida en el analizador ". La sintaxis de R contiene muchos casos ambiguos que deben resolverse de una forma u otra. El analizador elige resolver los bits de la expresión en diferentes órdenes dependiendo de si = o <- se utilizó.

Para comprender lo que está sucediendo, necesita saber que la asignación devuelve silenciosamente el valor que se le asignó. Puede ver eso más claramente al imprimir explícitamente, por ejemplo print(x <- 2 + 3).

En segundo lugar, es más claro si usamos la notación de prefijo para la asignación. Asi que

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 entonces sería

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

pero en realidad se interpreta como

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

Esto es porque = es menor prioridad que <-, como se muestra en el ?Syntax pagina de ayuda.


523
2017-11-16 14:36



La guía de estilo R de Google simplifica el problema al prohibir el "=" para la asignación. No es una mala elección.

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

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

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


87
2017-11-16 14:44



De acuerdo con John Chambers, el operador = solo está permitido en "el nivel superior", lo que significa que no está permitido en estructuras de control como if, haciendo que el siguiente error de programación sea ilegal.

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

Como él escribe, "no permitir la nueva forma de asignación [=] en las expresiones de control evita errores de programación (como el ejemplo anterior) que son más probables con el operador igual que con otras asignaciones S."

Puede hacer esto si está "aislado de la estructura lógica circundante, con llaves o un par adicional de paréntesis", por lo que if ((x = 0)) 1 else x trabajaría.

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


28
2018-01-28 18:34



x = y = 5 es equivalente a x = (y = 5), porque los operadores de asignación "grupo" de derecha a izquierda, que funciona. Significado: asignar 5 a ydejando el número 5; y luego asigne 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 5 a, umm, ¿qué exactamente?

Cuando mezcla los diferentes tipos de operadores de asignación, <- se une más fuerte que =. Asi que x = y <- 5 se interpreta como x = (y <- 5), que es el caso que tiene sentido.

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

Ver ?Syntax y ?assignOps para las reglas de precedencia (enlace) y agrupamiento.


26
2017-09-09 21:21



Los operadores <- y = asignar en el entorno en el que se evalúan. El operador <- se puede usar en cualquier lugar, mientras que el operador = solo está permitido en el nivel superior (por ejemplo, en la expresión completa escrita en el símbolo del sistema) o como una de las subexpresiones en una lista de expresiones respaldadas.


20
2017-11-16 12:21



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

Como muestra tu ejemplo, = y <- tiene precedencia de operador ligeramente diferente (que determina el orden de evaluación cuando se mezclan en la misma expresión). De hecho, ?Syntax en R da la siguiente tabla de precedencia del operador, de mayor a menor:

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

¿Pero esta es la única diferencia?

Ya que estabas preguntando sobre el Operadores de Asignación: sí, esa es la única diferencia. Sin embargo, serás perdonado por creer lo contrario. Incluso la documentación de R de ?assignOps afirma que hay más diferencias:

El operador <- se puede usar en cualquier lugar,   mientras que el operador = solo está permitido en el nivel superior (p.   en la expresión completa escrita en el símbolo del sistema) o como uno   de las subexpresiones en una lista respaldada de expresiones.

No pongámosle un punto demasiado fino: la documentación de R está (sutilmente) mal  [1]. Esto es fácil de mostrar: solo necesitamos encontrar un contraejemplo del = operador que no está (a) en el nivel superior, ni (b) una subexpresión en una lista de expresiones arrinconadas (es decir {…; …}) - Sin más preámbulos:

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

Claramente, hemos realizado una tarea, usando =, fuera de los contextos (a) y (b). Entonces, ¿por qué la documentación de una función básica del lenguaje R ha sido incorrecta durante décadas?

Es porque en la sintaxis de R el símbolo = tiene dos significados distintos que se combinan 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 token de sintaxis que señales nombre argumento pasando 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.

Veamos.

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

<nombre de la función>(<Argname> = <valor>, …)
<nombre de la función>(<Args>, <Argname> = <valor>, …)

… el = es el token que define el paso del argumento con nombre: es no el operador de asignación. Además, = es enteramente prohibido en algunos contextos sintácticos:

if (<Var> = <valor>) …
while (<Var> = <valor>) …
for (<Var> = <valor> in <Value2>) …
for (<Var1> in <Var2> = <valor>) …

Cualquiera de estos generará un error "inesperado" = "en <bla>".

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

median((x = 1 : 10))

Pero también:

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

Ahora puede objetar que dicho código es atroz (y puede que tenga razón). Pero tomé este código del base::file.copy función (reemplazando <- con =) - es un patrón generalizado en gran parte de la base del código R central.

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

[= la asignación está permitida solo en dos lugares en la gramática: en el nivel superior (como un programa completo o una expresión escrita por el usuario); y cuando está aislado de la estructura lógica circundante, mediante llaves o un par adicional de paréntesis.


Una confesión: mentí antes. Ahí es una diferencia adicional entre el = y <- operadores: llaman funciones distintas. Por defecto, estas funciones hacen lo mismo, pero puede anular cualquiera de ellas por separado para cambiar el comportamiento. Por el contrario, <- y -> (asignación de izquierda a derecha), aunque sintácticamente distinta, siempre llame al mismo función. Anular uno también anula al otro. Sabiendo esto es raramente práctico pero poder ser utilizado para algunas travesuras divertidas.


12
2017-07-27 19:17



Esto también puede aumentar la comprensión de la diferencia entre esos dos operadores:

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

Para el primer elemento R tiene valores asignados 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 (2016-10-31); macOS Sierra 10.12.1


4
2017-12-10 21:32