2012-04-01 11 views
17

Vorrei chiedere se è possibile copiare/spostare tutti gli oggetti di un ambiente in un altro, contemporaneamente. Per esempio:R: copia/sposta un ambiente ad un altro

f1 <- function() { 
    print(v1) 
    print(v2) 
} 

f2 <- function() { 
    v1 <- 1 
    v2 <- 2 

    # environment(f1)$v1 <- v1   # It works 
    # environment(f1)$v2 <- v2   # It works 

    environment(f1) <- environment(f2) # It does not work 
} 

f2() 
f1() 

TNX, in anticipo

risposta

22

Sembra che ci siano almeno 3 cose che si possono fare:

  1. Clonare un ambiente (creare un duplicato esatto)
  2. Copiare il contenuto di un ambiente ad un altro ambiente
  3. condividono lo stesso ambiente

Per Clone: ​​

# Make the source env 
e1 <- new.env() 
e1$foo <- 1 
e1$.bar <- 2 # a hidden name 
ls(e1) # only shows "foo" 

# This will clone e1 
e2 <- as.environment(as.list(e1, all.names=TRUE)) 

# Check it... 
identical(e1, e2) # FALSE 
e2$foo 
e2$.bar 

per copiare il contenuto, si può fare quello @gsk mostrato. Ma ancora una volta, la bandiera all.names è utile:

# e1 is source env, e2 is dest env 
for(n in ls(e1, all.names=TRUE)) assign(n, get(n, e1), e2) 

Per condividere l'ambiente è quello che ha fatto @koshke. Questo è probabilmente molto più utile. Il risultato è lo stesso come se la creazione di una funzione locale:

f2 <- function() { 
    v1 <- 1 
    v2 <- 2 

    # This local function has access to v1 and v2 
    flocal <- function() { 
    print(v1) 
    print(v2) 
    } 

    return(flocal) 
} 

f1 <- f2() 
f1() # prints 1 and 2 
+0

è una risposta completa –

9

Prova questa:

f2 <- function() { 
    v1 <- 1 
    v2 <- 2 
    environment(f1) <<- environment() 
} 
+0

Hai ragione, grazie mille! –

+0

+1 - nice one ... – Tommy

5

si potrebbe usare assegnazione:

f1 <- function() { 
    print(v1) 
    print(v2) 
} 

f2 <- function() { 
    v1 <- 1 
    v2 <- 2 

    for(obj in c("v1","v2")) { 
    assign(obj,get(obj),envir=f1.env) 
    } 
} 

Se non si desidera elencare il oggetti, ls() accetta un argomento di ambiente.

E si dovrà capire come ottenere f1.env di essere un ambiente che punta all'interno f1 :-)

+0

È una buona risposta –

+0

Nota che questo codice assegna semplicemente 'v1' e' v2' a '.GlovalEnv' ... – kohske

+0

Grazie! È stata una domanda divertente La soluzione di @Kohske sembra più elegante (come sempre!). –

1

per farlo:

environment(f1) <- environment(f2) # It does not work 

Aprire l'ambiente f1 ed eseguire fare questo:

ls(load(f2)) 
2

Io uso questa funzione nel mio pacchetto per copiare gli oggetti:

copyEnv <- function(from, to, names=ls(from, all.names=TRUE)) { 
    mapply(assign, names, mget(names, from), list(to), 
     SIMPLIFY = FALSE, USE.NAMES = FALSE) 
    invisible(NULL) 
} 
Problemi correlati