tutorial - tablas en r
¿Cómo puedo hacer referencia al entorno local dentro de una función, en R? (1)
[Esta pregunta se resolvió en la sala de chat, por Spacedman , pero la publicaré para el beneficio de otros en el futuro.]
Tengo una función, myFunc
, que crea localFunc
dentro de ella. (NB: esto no está en un paquete, sino en el entorno global). Me gustaría saber dónde existe localFunc
en la ruta de búsqueda, ya que me gustaría analizarlo a través de mvbutils::foodweb
.
Aquí hay un ejemplo:
myFunc <- function(){
require(data.table)
require(mvbutils)
localFunc <- function(x){
return(as.data.table(x))
}
vecPrune <- c("localFunc",ls("package:data.table"))
ix <- match("data.table",search())
tmpWeb <- foodweb(where = c(1,ix), prune = vecPrune, plotting = FALSE)
return(tmpWeb)
}
Sin embargo, una llamada a myFunc()
no parece indicar que localFunc
llama a data.table()
. Esto es incorrecto, ¿qué da?
(NB: el argumento where
especifica la ruta de búsqueda.)
Actualización 1: como señalan Tommy y Spacedman, el truco es especificar el environment()
. La llamada a foodweb()
refiere a where = c(1, ix)
. El índice 1
es un error. Eso surgió de pensar que .GlobalEnv
, que es a menudo (¿siempre?) El primer elemento en el vector search()
, es el lugar correcto para buscar. Eso es erróneo. En su lugar, uno debe referirse al environment()
, y la llamada correcta se encuentra a continuación. (NB: ix
especifica la ubicación de data.table()
en la salida de search()
).
tmpWeb <- foodweb(where = c(environment(),ix), prune = vecPrune, plotting = FALSE)
Esto aparece en la respuesta a esta pregunta , en una función llamada checkScriptDependencies
, que envuelve el código de un archivo de script R en una función local, que luego es analizada por foodweb
. Este es un ejemplo limitado de cómo usar el environment()
, y Tommy ha dado una buena explicación de cómo usarlo y funciones similares en este contexto.
Para obtener el entorno actual, simplemente llame a environment()
.
En general, sys.frame
devuelve cualquiera de los entornos que se encuentran actualmente en la pila de llamadas, y sys.nframe
devuelve la profundidad actual de la pila de llamadas. sys.frames
devuelve una lista de todos los entornos en la pila de llamadas.
environment(f)
devuelve el entorno de cierre para una función f
(donde buscará funciones y variables globales).
parent.env(e)
devuelve el entorno principal donde se verá si no se encuentra un símbolo en e
.
f <- function() {
function() list(curEnv=environment(), parent=parent.env(environment()),
grandParent=parent.env(parent.env(environment())), callStack=sys.frames(),
callStackDepth=sys.nframe())
}
g <- function(f, n=2) if (n>2) g(f, n-1) else f()
floc <- f() # generate a local function
g(floc, 3) # call it
Esto llamará a la función local floc
con una profundidad de pila de 3. Devuelve una lista con el entorno actual, es padre (el entorno local en f
) y es padre genérico (donde se definió f
, globalenv
). También devuelve la lista de marcos de pila (entornos). Estos son los entornos para las llamadas recursivas en g
(excepto el último que es el entorno actual de floc
).