studio pipes operator r rstudio

pipes - Operador “[<-” en RStudio y R



pipe rstudio (1)

Por accidente me he encontrado con un comportamiento extraño del operador "[<-" . Se comporta de manera diferente según el orden de las llamadas y si estoy usando RStudio o simplemente RGui ordinario. Me aclararé con un ejemplo.

x <- 1:10 "[<-"(x, 1, 111) x[5] <- 123

Por lo que sé, la primera asignación no debería cambiar x (¿o tal vez me equivoque?), Mientras que la segunda no debería cambiar. Y de hecho el resultado de las operaciones anteriores es

x [1] 1 2 3 4 123 6 7 8 9 10

Sin embargo, cuando realizamos estas operaciones en un orden diferente, los resultados son diferentes y ¡ x ha cambiado! Con aire significativo:

x <- 1:10 x[5] <- 123 "[<-"(x, 1, 111) x [1] 111 2 3 4 123 6 7 8 9 10

¡Pero solo sucede cuando estoy usando R simple! En RStudio el comportamiento es el mismo en ambas opciones. Lo he comprobado en dos máquinas (una con Fedora, una con Win7) y la situación es exactamente igual. Sé que la versión ''funcional'' ( "[<-"(x..) ) probablemente nunca se use, pero tengo mucha curiosidad de por qué está sucediendo. ¿Alguien podría explicar eso?

==========================

EDIT: Ok, entonces, de los comentarios que obtengo que la razón fue que x <- 1:10 tiene el tipo ''entero'' y después de reemplazar x[5] <- 123 es ''doble''. Pero aún queda pregunta por qué el comportamiento es diferente en RStudio? Reinicio la sesión R y no cambia nada.


Comportamiento de rstudio

El navegador de objetos de Rstudio modifica los objetos que examina de una manera que obliga a copiarlos en la modificación. Específicamente, el navegador de objetos emplea al menos una función R cuya llamada fuerza internamente la evaluación del objeto, en el proceso de restablecer el valor del campo nombrado del objeto de 1 a 2. En el manual de R-Internals :

Cuando un objeto está a punto de ser alterado, se consulta el campo nombrado. Un valor de 2 significa que el objeto debe estar duplicado antes de ser cambiado. [...] Se usa un valor de 1 para situaciones donde [...] en principio existen dos copias de una para la duración del cálculo [...] pero ya no, por lo que algunas funciones primitivas pueden optimizarse Para evitar una copia en este caso.

Para ver que el navegador de objetos modifica el campo nombrado ( [NAM()] en el siguiente bloque de código), compare los resultados de la ejecución de las siguientes líneas. En la primera, ambas ''líneas'' se ejecutan juntas, de modo que Rstudio no tiene tiempo para ''tocar'' X antes de consultar su estructura. En la segunda, cada línea se pega por separado, de modo que X se modifica antes de examinarla.

## Pasted in together x <- 1:10; .Internal(inspect(x)) # @46b47b8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,... ## Pasted in with some delay between lines x <- 1:10 .Internal(inspect(x)) # @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...

Una vez que el campo nombrado se establece en 2, [<-(X, ...) no modificará el objeto original. Pegar lo siguiente en Rstudio al mismo tiempo modifica X , mientras que pegarlo línea por línea no:

x <- 1:10 "[<-"(x, 1, 111)

Una consecuencia más de todo esto es que el buscador de objetos de Rstudio en realidad hace que algunas operaciones sean más lentas de lo que serían. Nuevamente, compare los dos comandos primero pegados juntos, y luego uno a la vez:

## Pasted in together x <- 1:5e7 system.time(x[1] <- 9L) # user system elapsed # 0 0 0 ## Pasted in one at a time x <- 1:5e7 system.time(x[1] <- 9L) # user system elapsed # 0.11 0.04 0.16

Comportamiento variable de [<- en R

El comportamiento de [<- wrt modificando un vector X depende de los tipos de almacenamiento de X y del elemento que se le asigna. Esto explica el comportamiento de R pero no el de Rstudio.

En R, cuando [<- agrega a un vector X , o realiza una subasignación que requiere que se modifique el tipo de X , X se copia y el valor que se devuelve no sobrescribe la variable X preexistente. (Para hacer eso necesitas hacer algo como X <- "[<-(X, 2, 100) .

Por lo tanto, ninguno de los siguientes modifica X

X <- 1:2 ## Note: typeof(X) --> "integer" ## Subassignment that requires that X be coerced to "numeric" type "[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric" X # [1] 1 2 ## Appending to X "[<-"(X, 3, 100L) X # [1] 1 2

Sin embargo, siempre que sea posible, R permite que la función [<- modifique X directamente por referencia (es decir, sin hacer una copia). "Posible" aquí incluye casos en los que una subasignación no requiere que se modifique el tipo de X

Así que todos los siguientes modifican X

X <- c(0i, 0i, 0i, 0i) "[<-"(X, 1, TRUE) "[<-"(X, 2, 20L) "[<-"(X, 3, 3.14) "[<-"(X, 4, 5+5i) X # [1] 1.00+0i 20.00+0i 3.14+0i 5.00+5i