¿Por qué es malo usar asignar?

Resuelto asb asked hace 54 años • 3 respuestas

Esta publicación ( Evaluación diferida en R: ¿se ve afectada la asignación? ) cubre algunos puntos en común, pero no estoy seguro de que responda mi pregunta.

Dejé de consumir assigncuando descubrí la applyfamilia hace bastante tiempo, aunque sea por pura cuestión de elegancia en situaciones como esta:

names.foo <- letters
values.foo <- LETTERS
for (i in 1:length(names.foo))
  assign(names.foo[i], paste("This is: ", values.foo[i]))

que puede ser reemplazado por:

foo <- lapply(X=values.foo, FUN=function (k) paste("This is :", k))
names(foo) <- names.foo

Esta es también la razón por la que esto ( http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-can-I-turn-a-string-into-a-variable_003f ) R-faq dice que esto debería evitarse.

Ahora, sé que eso assigngeneralmente está mal visto. ¿Pero hay otras razones que no sé? Sospecho que puede afectar el alcance o la evaluación diferida, pero no estoy seguro. El código de ejemplo que demuestre tales problemas será excelente.

asb avatar Jan 01 '70 08:01 asb
Aceptado

En realidad esas dos operaciones son bastante diferentes. El primero te ofrece 26 objetos diferentes mientras que el segundo solo te ofrece uno. El segundo objeto será mucho más fácil de utilizar en los análisis. Entonces, supongo que diría que ya ha demostrado la principal desventaja de assign, es decir, la necesidad de tener que usarlo siempre getpara acorralar o reunir todos los objetos individuales con nombres similares que ahora están "sueltos" en el entorno global. Intenta imaginar cómo harías cualquier cosa en serie con esos 26 objetos separados. Una simple lapply(foo, func)será suficiente para la segunda estrategia.

Esa cita de preguntas frecuentes en realidad solo dice que usar la asignación y luego asignar nombres es más fácil, pero no implica que sea "malo". Lo leo como "menos funcional", ya que en realidad no devuelve un valor asignado. El efecto parece ser un efecto secundario (y en este caso la assignestrategia resulta en 26 efectos secundarios separados). El uso de assignparece ser adoptado por personas que provienen de lenguajes que tienen variables globales como una forma de evitar adoptar el "True R Way", es decir, programación funcional con objetos de datos. Realmente deberían aprender a usar listas en lugar de llenar su espacio de trabajo con elementos con nombres individuales.

Existe otro paradigma de asignación que se puede utilizar:

 foo <- setNames(  paste0(letters,1:26),  LETTERS)

Eso crea un vector atómico con nombre en lugar de una lista con nombre, pero el acceso a los valores en el vector todavía se realiza con los nombres dados a [.

IRTFM avatar Jul 09 '2013 22:07 IRTFM

Como fuente fortune(236)pensé en agregar un par de ejemplos (ver también fortune(174)).

Primero, una prueba. Considere el siguiente código:

x <- 1
y <- some.function.that.uses.assign(rnorm(100))

Después de ejecutar las 2 líneas de código anteriores, ¿cuál es el valor de x?

La assignfunción se utiliza para realizar "Acción a distancia" (consulte http://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming) o busque en Google). Esta es a menudo la fuente de errores difíciles de encontrar.

Creo que el mayor problema assignes que tiende a llevar a las personas por caminos de pensamiento que las alejan de mejores opciones. Un ejemplo simple son los 2 conjuntos de códigos de la pregunta. La lapplysolución es más elegante y debería promoverse, pero el mero hecho de que la gente conozca la assignfunción los lleva a la opción del bucle. Luego deciden que necesitan hacer la misma operación en cada objeto creado en el bucle (lo que sería simplemente otra solución simple lapplyo sapplysi se usara la solución elegante) y recurren a un bucle aún más complicado que involucra ambos gety applyjunto con feas llamadas a paste. Entonces los enamorados assignintentan hacer algo como:

curname <- paste('myvector[', i, ']')
assign(curname, i)

Y eso no hace exactamente lo que esperaban, lo que lleva a quejarse de R (lo cual es tan justo como quejarse de que la casa de mi vecino de al lado está demasiado lejos porque elegí caminar el camino más largo alrededor de la cuadra) o, peor aún, a profundizar. en usar evaly parsehacer que su cadena construida "funcione" (lo que luego conduce a fortune(106)y fortune(181)).

Greg Snow avatar Jul 10 '2013 16:07 Greg Snow

Me gustaría señalar que assigndebe usarse con environments.

Desde ese punto de vista, lo "malo" del ejemplo anterior es utilizar una estructura de datos no del todo apropiada (el entorno base en lugar de a listo data.frame, vector, ...).

Nota al margen: también para environments, los operadores $y $<-funcionan, por lo que en muchos casos lo explícito assigny gettampoco es necesario allí.

cbeleites unhappy with SX avatar Jul 10 '2013 06:07 cbeleites unhappy with SX