2012-03-15 8 views
13

Un post qui su un giorno indietro mi chiede come assegnare valori a più oggetti nell'ambiente globale all'interno di una funzione. Questo è il mio tentativo di utilizzare lapply (assign potrebbe essere più sicuro di <<- ma non l'ho mai effettivamente utilizzato e non ho familiarità con esso).Assegna più oggetti a .GlobalEnv dall'interno di una funzione

#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]]) 

Non esitate a ridurre qualsiasi/tutte le parti del mio codice per fare questo lavoro (o di lavorare meglio/più veloce).

+3

Questa domanda o ogni risposta dovrebbe venire con un grande "Figli, non farlo a casa!" disclaimer. Come forse sapete, le assegnazioni globali all'interno delle funzioni sono una ricetta per il disastro o "la vita di un vulcano" per citare Richard Burns (http://www.burns-stat.com/pages/Tutor/R_inferno.pdf) – flodel

+0

@flodel Non sono programmatore, quindi puoi spiegare brevemente qual è il problema con assegnare? –

+0

Quindi ho letto la sezione che hai citato. Sembra intelligente per il codice per il consumo pubblico ma non per il codice personale. Riesci a vedere un modo per raggiungere questo effetto senza? –

risposta

22

Hai ragione che lo assign() è lo strumento giusto per il lavoro. L'argomento envir offre un controllo preciso su dove si svolge l'assegnazione, controllo non disponibile con <- o <<-.

Così, per esempio, per assegnare il valore di X ad un oggetto denominato NAME nel contesto globale, si dovrebbe fare:

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

Nel tuo 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

Grazie. Sapevo che << << - 'è una cattiva forma ma è stato pigro. Prenderò l'abitudine di usare 'assign'. In realtà ho avuto esattamente quello che fai a un certo punto ma ho pensato che non dovevo mettere le virgolette attorno agli Oggetti come avevo già pre assegnato loro. Questo è più facile in qualsiasi modo. –

+0

Sì. Usare 'assign()' è una di quelle cose che sembrano una gobba da superare prima di provarlo, ma una volta che lo fai, ti chiedi perché mai hai avuto qualche esitazione in primo luogo. –

+0

+1 - oro. Ho dovuto assegnare tutti gli oggetti in un ambiente all'ambiente globale proprio ora, e questa soluzione mi ha fatto risparmiare tempo a pensarci. – ricardo