2012-03-05 9 views
11

Estoy tratando de usar asignar valores en un objeto en una lista. Lo que quiero hacer es cambiar algunos elementos. Por ejemplo:¿Por qué los valores de assign() a un elemento de lista no funcionan en R?

x <- list() 
x$test <- 1 
assign("x$test", 2) 
x$test == 1 
    [1] TRUE 

¿Alguna idea? Necesito usar asignar porque estoy construyendo una función que tomará los nombres de los objetos dentro de la lista (x) como entradas.

+0

Nota, hay una gran diferencia entre 'x $ test' y' x [['test']] '. Ver el documento en ['extract (..., drop = TRUE)'] (https://stat.ethz.ch/R-manual/R-devel/library/base/html/Extract.html) – smci

Respuesta

13

Parece que está de enhorabuena. Desde el archivo de ayuda:

'Asignar' no despachar métodos de asignación, por lo que no se puede utilizar para conjunto de elementos de vectores, nombres, atributos, etc.

Note que la asignación en un listado adjunto o el marco de datos cambia la copia adjunta y no el objeto original: consulte 'adjuntar' y 'con'.

Si va a ceder names(x) como entrada, no se puede utilizar:

nms <- names(x) 
for (n in nms) 
    x[[n]] <- 'new_value' 

Además, estás intención para su función de modificar alguna variable global? e.g .:

x <- list(test=1) 

f <- function(...) 
    x$test <- 2 

f() # want x$test = 2 ?? 

Porque esto no funcionará (problemas de alcance). Puede hacer que funcione con un poco de trabajo de pies (<<-), pero esto generalmente se considera una mala práctica ya que es fácil introducir errores involuntarios en su código.

Si pudiera dar un ejemplo de por qué desea esta función/para qué sirve, podríamos ayudarlo a encontrar una solución alternativa.

+0

Genial, muchas gracias, no sabía que podía usar la sintaxis [[n]], que es totalmente suficiente. Realmente aprecio la información. – mike

8

ver lo que sucede cuando se asigna a "x $ test":

x <- list() 
x$test <- 1 
assign("x$test", 2) 
ls() 
[1] "x"  "x$test" 

El elemento "prueba" en "x" es igual: 1, y se extraen con x$test pero get("x$test") será el valor 2 de ese nombre.

¿Por qué no usar los nombres directamente? Es decir.

this.name <- "test" 
x[[this.name]] <- 2 
+0

No sé por qué se ha aceptado la otra respuesta, pero como dice mdsumner, ¿por qué no usar el nombre directamente? eso funciona absolutamente perfecto. – user1052080

+0

assign() le permite especificar el entorno en el que se realiza la tarea, lo que puede ser muy útil. Esto está en contraste con << - que solo asigna al entorno global. Entonces, x [[nombre]] no es una solución tan general como sería asignar (x $ nombre, valor, envir = mi_env). –

1

Otra solución es:

x <- list() 
x$test <- 1 
assign("x$test", 2) 
x$test == 1 
TRUE 
eval(parse(text="x$test<-2")) 
x$test == 1 
FALSE 

El comando eval(parse(text="")) puede ser muy útil en este contexto.

Atentamente

+4

Parafraseando a Thomas Lumley: "Si la respuesta es parse(), por lo general, deberías reconsiderar la pregunta". Evite construcciones como esta en todo momento si hay una solución más sensata. Aquí esa solución es '[[' –

Cuestiones relacionadas