sintaxis programación programacion operadores logicos lenguaje funciones estadistica español ejemplos byrow r assignment-operator r-faq

programación - manual de r estadistica en español



¿Cuáles son las diferencias entre “=” y “<-” en R? (7)

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

Como muestra su ejemplo, = y <- tienen una precedencia de operadores ligeramente diferente (lo 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 preguntaba sobre los operadores asignados : 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 preparadas.

No le pongamos demasiada importancia: la documentación de R es (sutilmente) incorrecta [ http://developer.r-project.org/equalAssign.html ] . Esto es fácil de mostrar: solo tenemos que encontrar un contraejemplo del operador = que no esté (a) en el nivel superior, ni (b) una subexpresión en una lista de expresiones preparadas (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 del lenguaje R central 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 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 pieza de código de la forma general ...

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

... el = es el token que define el paso del argumento con nombre: no es el operador de asignación. Además, = está 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 generará un error "inesperado ''='' en ‹bla›".

En cualquier otro contexto, = 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 una tarea:

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 función base::file.copy (reemplazando <- con = ) - es un patrón generalizado en gran parte de la base de código de Core R.

La http://developer.r-project.org/equalAssign.html , en la que probablemente se basa la documentación de la R, explica esto correctamente:

[ = asignación está permitida] solo en dos lugares de 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 extra de paréntesis.

Una confesión: mentí antes. Hay una diferencia adicional entre los operadores = y <- : 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 distintas, siempre llaman a la misma función. Anular uno también anula al otro. Saber esto rara vez es práctico, pero se puede usar para algunos chanchullos divertidos .

¿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 es esta la única diferencia?


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


La diferencia en los operadores de asignación es más clara cuando los usa para establecer un valor de 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, se declara x en el espacio de trabajo del usuario, por lo que puede usarlo una vez que se haya completado la llamada a la función.

Existe una preferencia general entre la comunidad R por usar <- para la asignación (excepto en firmas de funciones) por compatibilidad con versiones (muy) 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 IDE R tienen métodos abreviados de teclado para hacer que <- sea ​​más fácil de escribir. Ctrl + = en Arquitecto, Alt + - en RStudio ( Opción + - bajo macOS), Shift + - (guión bajo) en emacs + ESS.

Si prefiere escribir = a <- pero desea usar el símbolo de asignación más común para el código publicado públicamente (en CRAN, por ejemplo), puede usar 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 arroja un error pero no x <- y <- 5 ?" es "Se trata 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 se usó = o <- .

Para comprender lo que está sucediendo, debe saber que la asignación devuelve silenciosamente el valor asignado. Puede verlo más claramente imprimiendo 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 sería entonces

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

pero en realidad se interpreta como

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

Esto se debe a que = tiene una prioridad menor que <- , como se muestra en la página de ayuda ?Syntax .



Los operadores <- y = asignan al entorno en el que son evaluados. 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 preparadas.


Según John Chambers, el operador = solo se permite en "el nivel superior", lo que significa que no está permitido en las estructuras de control como if , lo que hace que el siguiente error de programación sea ilegal.

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

Mientras 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 S asignaciones".

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

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


x = y = 5 es equivalente a x = (y = 5) , porque los operadores de asignación "agrupan" de derecha a izquierda, lo que funciona. Significado: asigna 5 a y , dejando el número 5; y luego asigna ese 5 a x .

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

Cuando mezcla los diferentes tipos de operadores de asignación, <- enlaza más apretado que = . Entonces 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.

Consulte ?Syntax y ?assignOps para las ?assignOps de precedencia (enlace) y agrupación.