¿Cuáles son las diferencias entre los operadores de asignación =
y <-
en R?
Como muestra su ejemplo, =
y <-
tienen una 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 de operadores, de mayor a menor:
…
‘-> ->>’ rightwards assignment
‘<- <<-’ assignment (right to left)
‘=’ assignment (right to left)
…
¿Pero es esta la única diferencia?
Como estaba preguntando acerca de los operadores de asignación : sí, esa es la única diferencia. Sin embargo, sería perdonado por creer lo contrario. Incluso la documentación R de ?assignOps
afirma que hay más diferencias:
El operador <-
se puede usar en cualquier lugar, mientras que el operador =
solo se permite 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 entre paréntesis.
No pongámosle un punto demasiado fino: la documentación de R es (sutilmente) incorrecta [ 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 entre paréntesis (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, utilizando =
, fuera de los contextos (a) y (b). Entonces, ¿por qué la documentación de una característica principal del lenguaje R ha estado mal durante décadas?
Es porque en la sintaxis de R el símbolo =
tiene dos significados distintos que se combinan habitualmente:
- El primer significado es como operador de asignación . Esto es todo de lo que hemos hablado hasta ahora.
- El segundo significado no es un operador, sino más bien un token de sintaxis que señala un argumento con nombre 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.
Veamos.
En cualquier código de la forma general ...
‹function_name›(‹argname› = ‹value›, …)
‹function_name›(‹args›, ‹argname› = ‹value›, …)
... el =
es el símbolo que define el llamado argumento que pasa: es no el operador de asignación. Además, =
está completamente 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 generará un error “inesperado '=' en ‹bla›”.
En cualquier otro contexto, se =
refiere a la llamada del operador de asignación. En particular, simplemente poner paréntesis alrededor de la subexpresión hace que cualquiera de los anteriores (a) sea válido y (b) una 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 de la base::file.copy
función (reemplazando <-
con =
): es un patrón generalizado en gran parte de la base de código R principal.
La explicación original de John Chambers , en la que probablemente se basa la documentación de R, en realidad explica esto correctamente:
[la =
asignación está] permitida en solo dos lugares en la gramática: en el nivel superior (como un programa completo o una expresión escrita por el usuario); y cuando se aísla de la estructura lógica circundante, mediante llaves o un par adicional de paréntesis.
Una confesión: mentí antes. No es una diferencia adicional entre el =
y <-
los operadores: se llama a 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 distintas, siempre llaman a la misma función. Anular uno también anula al otro. Saber esto rara vez es práctico, pero puede usarse para algunas travesuras divertidas .
<-
símbolo provienen de viejos teclados APL que en realidad tenían una sola<-
tecla.