Aggiornamento 2 @G. Grothendieck ha pubblicato due approcci. Il secondo sta cambiando l'ambiente della funzione all'interno di una funzione. Questo risolve il mio problema di troppi repliche di codifica. Non sono sicuro che questo sia un buon metodo per passare il controllo CRAN quando si creano i miei script in un pacchetto. Aggiornerò di nuovo quando avrò delle conclusioni.In R, come rendere le variabili all'interno di una funzione disponibile per la funzione di livello inferiore all'interno di questa funzione? (Con, allegare, ambiente)
Aggiornamento
Sto cercando di passare un sacco di variabili degli argomenti di input per f2
e non voglio indicizzare tutte le variabili all'interno della funzione come env$c, env$d, env$calls
, è per questo che ho cercato di utilizzare with
in f5
e f6
(modificato f2
). Tuttavia, assign
non funziona con with
all'interno del {}
, spostando assign
fuori with
farà il lavoro, ma nel mio caso reale ho alcune assign
s all'interno delle with
espressioni che non so come muoversi fuori della funzione with
facilmente .
Ecco un esempio:
## In the <environment: R_GlobalEnv>
a <- 1
b <- 2
f1 <- function(){
c <- 3
d <- 4
f2 <- function(P){
assign("calls", calls+1, inherits=TRUE)
print(calls)
return(P+c+d)
}
calls <- 0
v <- vector()
for(i in 1:10){
v[i] <- f2(P=0)
c <- c+1
d <- d+1
}
return(v)
}
f1()
Funzione f2
è dentro f1
, quando f2
si chiama, cerca le variabili calls,c,d
nell'ambiente environment(f1)
. Questo è quello che volevo.
Tuttavia, quando voglio utilizzare f2
anche nelle altre funzioni, definirò questa funzione nell'ambiente Globale, chiamiamolo f4
.
f4 <- function(P){
assign("calls", calls+1, inherits=TRUE)
print(calls)
return(P+c+d)
}
Questo non funziona, perché cercherà calls,c,d
nell'ambiente globale invece che all'interno di una funzione in cui viene chiamata la funzione. Ad esempio:
f3 <- function(){
c <- 3
d <- 4
calls <- 0
v <- vector()
for(i in 1:10){
v[i] <- f4(P=0) ## or replace here with f5(P=0)
c <- c+1
d <- d+1
}
return(v)
}
f3()
Il modo sicuro dovrebbe essere definire calls,c,d
negli argomenti ingresso f4
e quindi passare questi parametri in f4
. Tuttavia, nel mio caso ci sono troppe variabili da passare in questa funzione f4
e sarebbe meglio che io possa passarlo come un ambiente e dire f4
non guardare nell'ambiente Globale (environment(f4)
), guardare solo all'interno dello environment
quando viene chiamato f3
.
Il modo in cui lo risolvo ora è utilizzare l'ambiente come un elenco e utilizzare la funzione with
.
f5 <- function(P,liste){
with(liste,{
assign("calls", calls+1, inherits=TRUE)
print(calls)
return(P+c+d)
}
)
}
f3 <- function(){
c <- 3
d <- 4
calls <- 0
v <- vector()
for(i in 1:10){
v[i] <- f5(P=0,as.list(environment())) ## or replace here with f5(P=0)
c <- c+1
d <- d+1
}
return(v)
}
f3()
Tuttavia, ora assign("calls", calls+1, inherits=TRUE)
non funziona come dovrebbe essere dato assign
non modifica l'oggetto originale. La variabile calls
è collegata a una funzione di ottimizzazione in cui la funzione obiettivo è f5
. Questo è il motivo per cui utilizzo assign
anziché passare calls
come argomenti di input. Anche l'utilizzo di attach
non mi è chiaro.Qui è il mio modo per risolvere il problema assign
:
f7 <- function(P,calls,liste){
##calls <<- calls+1
##browser()
assign("calls", calls+1, inherits=TRUE,envir = sys.frame(-1))
print(calls)
with(liste,{
print(paste('with the listed envrionment, calls=',calls))
return(P+c+d)
}
)
}
########
##################
f8 <- function(){
c <- 3
d <- 4
calls <- 0
v <- vector()
for(i in 1:10){
##browser()
##v[i] <- f4(P=0) ## or replace here with f5(P=0)
v[i] <- f7(P=0,calls,liste=as.list(environment()))
c <- c+1
d <- d+1
}
f7(P=0,calls,liste=as.list(environment()))
print(paste('final call number',calls))
return(v)
}
f8()
io non sono sicuro di come questo dovrebbe essere fatto in R. Sono sulla strada giusta, soprattutto quando passa attraverso il CRAN controllare? Qualcuno ha qualche suggerimento su questo?
Questo dà il risultato che voglio ma non ho scritto chiaramente la mia richiesta. Infatti, voglio evitare di indicizzare tutte le variabili che passano in 'f2', cioè non scrivere' env $ ', ecco perché ho provato ad usare' with'. Voglio essere in grado di modificare le 'chiamate' esterne dentro' f2' ma non modificare le altre variabili nell'ambiente corrente. Aggiornerò la domanda – Zhenglei
Ho aggiunto un secondo approccio. –
Sembra proprio quello di cui ho bisogno. Lo metterò alla prova con il mio caso reale e aggiornerò più tardi. Grazie mille per l'aiuto! – Zhenglei