2012-03-15 24 views
13

Una publicación aquí un día atrás me ha preguntado cómo asignar valores a múltiples objetos en el entorno global desde dentro de una función. Este es mi intento de usar lapply (assign puede ser más seguro que <<- pero nunca lo he usado y no estoy familiarizado con él).Asignar múltiples objetos a .GlobalEnv desde una función

#fake data set 
df <- data.frame(
    x.2=rnorm(25), 
    y.2=rnorm(25), 
    g=rep(factor(LETTERS[1:5]), 5) 
) 

#split it into a list of data frames 
LIST <- split(df, df$g) 

#pre-allot 5 objects in R with class data.frame() 
V <- W <- X <- Y <- Z <- data.frame() 

#attempt to assign the data frames in the LIST to the objects just created 
lapply(seq_along(LIST), function(x) c(V, W, X, Y, Z)[x] <<- LIST[[x]]) 

dude en acortar cualquier/todas las partes de mi código para hacer este trabajo (o trabajar mejor/más rápido).

+3

Esta pregunta o cualquier respuesta debería venir con un gran "Niños, no hagas esto en casa". renuncia. Como sabrá, las asignaciones globales dentro de las funciones son una receta para el desastre, o "la vida de un volcán" para citar a Richard Burns (http://www.burns-stat.com/pages/Tutor/R_inferno.pdf) – flodel

+0

@flodel No soy programador, ¿puedes explicar brevemente el problema con asignar? –

+0

Así que leí la sección que citó. Eso parece inteligente para el código de consumo público pero no para el código personal. ¿Puedes ver una forma de lograr este afecto sin? –

Respuesta

22

Tienes razón en que assign() es la herramienta adecuada para el trabajo. Su argumento envir le da un control preciso sobre dónde se realiza la asignación, control que no está disponible con <- o <<-.

Así, por ejemplo, para asignar el valor de X a un objeto denominado NAME en el medio ambiente global, que haría:

assign("NAME", X, envir = .GlobalEnv) 

En su caso:

df <- data.frame(
    x.2=rnorm(25), 
    y.2=rnorm(25), 
    g=rep(factor(LETTERS[1:5]), 5) 
) 
LIST <- split(df, df$g) 
NAMES <- c("V", "W", "X", "Y", "Z") 

lapply(seq_along(LIST), 
     function(x) { 
      assign(NAMES[x], LIST[[x]], envir=.GlobalEnv) 
     } 
) 

ls() 
[1] "df" "LIST" "NAMES" "V"  "W"  "X"  "Y"  "Z"  
+0

Gracias. Sabía que << << - 'es mala forma pero ha sido flojo. Adquiriré el hábito de usar 'assign'. De hecho, tuve exactamente lo que haces en un momento, pero pensé que no debería poner comillas alrededor de los Objetos, como ya los había asignado. Esto es más fácil de cualquier manera. –

+0

Sí. Usar 'assign()' es una de esas cosas que se ve como una joroba que superar antes de probarlo, pero una vez que lo haces, te preguntas por qué alguna vez dudaste en primer lugar. –

+0

+1 - dorado. Tuve que asignar todos los objetos en un entorno al entorno global en este momento, y esta solución me ahorró tener que pensarlo. – ricardo

Cuestiones relacionadas