inteligentes inteligente instrumentos instrumentacion definicion r scope

instrumentos - definicion instrumentacion inteligente



Limitar el alcance de la variable (4)

Intento escribir una función, lo que limita el alcance de las variables R. Por ejemplo,

source("LimitScope.R") y = 0 f = function(){ #Raises an error as y is a global variable x = y }

Pensé en probar el entorno variable, pero no estaba realmente seguro de cómo hacer esto.

El porque

Enseño R a los estudiantes de licenciatura. En sus primeras prácticas, algunos de ellos siempre olvidan el alcance variable, por lo que las funciones enviadas no funcionan. Por ejemplo, siempre obtengo algo así como:

n = 10 f = function(x){ #Raises an error #as I just source f and test it for a few test cases. return(x*n) }

Estaba buscando una función rápida que "apague" el alcance. Como se puede imaginar, no tiene que ser particularmente robusto, ya que solo se ofrecería para las pocas prácticas.


No estoy seguro de que quiera hacer esto en general, pero la función local() debería ayudar, al igual que la biblioteca codetools .

En tu ejemplo, prueba

f = local( function() { ... }, baseenv())

No hace exactamente lo que quiere, pero debe acercarse más.


Puedes verificar si y existe en el entorno global usando exists(''y'',envir=.GlobalEnv)


Puede forzar una variable para que sea la versión local con esta función:

get_local <- function(variable) { get(variable, envir = parent.frame(), inherits = FALSE) }

Compare estos casos

y <- 0 f <- function() { x <- y } print(f()) # 0 y <- 0 f <- function() { y <- get_local("y") x <- y } print(f()) # Error: ''y'' not found

Dependiendo de lo que esté haciendo, también puede verificar si y era un argumento para f , usando formalArgs o formalArgs .

g <- function(x, y = TRUE, z = c("foo", "bar"), ...) 0 formalArgs(g) # [1] "x" "y" "z" "..." formals(g) #$x # # #$y #[1] TRUE # #$z #c("foo", "bar") # #$...

EDITAR: El punto más general de "cómo desactivar el ámbito léxico sin cambiar el contenido de las funciones" es más difícil de resolver. Estoy bastante seguro de que las reglas de alcance están bastante arraigadas en R. Una alternativa podría ser usar S-Plus, ya que tiene diferentes reglas de alcance .


Lo que ocasionalmente me pasa es que tengo una pantalla dividida en ESS con un buffer de archivo de código R a la izquierda y el intérprete a la derecha. Es posible que haya establecido algunos valores en el intérprete mientras depuro el código en el que estoy trabajando en el búfer. Entonces es posible que el código en el buffer accidentalmente refereneces algo que puse en el intepreter. Es difícil detectar el problema a menos que evalúe mi búfer en un intérprete nuevo cada vez, que no es así como funciona ESS por defecto.

Si este es el tipo de problema que está viendo con frecuencia, una rm (list = ls (envir = .GlobalEnv)) en la fuente puede ayudar, pero eso por supuesto crea otros problemas, como borrar cualquier cosa que estén usando para mantener estado mientras se depura, etc.