programacion producto funciones funcion for escalar ejercicios ejemplos comandos ciclo r scope

producto - if en r



Escribir funciones en R, teniendo en cuenta el alcance (4)

A menudo escribo funciones que necesitan ver otros objetos en mi entorno. Por ejemplo:

> a <- 3 > b <- 3 > x <- 1:5 > fn1 <- function(x,a,b) a+b+x > fn2 <- function(x) a+b+x > fn1(x,a,b) [1] 7 8 9 10 11 > fn2(x) [1] 7 8 9 10 11

Como se esperaba, ambas funciones son idénticas porque fn2 puede "ver" ayb cuando se ejecuta. Pero cada vez que empiezo a aprovechar esto, en aproximadamente 30 minutos termino llamando a la función sin una de las variables necesarias (por ejemplo, aob). Si no aprovecho esto, entonces siento que estoy pasando objetos innecesariamente.

¿Es mejor ser explícito acerca de lo que requiere una función? ¿O debería hacerse cargo de esto a través de comentarios en línea u otra documentación de la función? ¿Hay una mejor manera?


¿Se produce el problema cuando solo estás utilizando una variable global en una función o cuando intentas asignar la variable? Si es lo último, sospecho que es porque no estás usando <<- como una asignación dentro de la función. Y mientras que el uso de <<- parece ser el lado oscuro 1 , puede muy bien funcionar para tus propósitos. Si es el primero, la función probablemente está enmascarando la variable global.

Nombrar variables globales de una manera en la que sería difícil enmascararlas localmente podría ayudar. por ejemplo: global.pimultiples <- 1:4*pi


El uso de variables globales está generalmente desaconsejado en la mayoría de los idiomas, y R no es una excepción. Muy a menudo, las funciones cortas utilizan nombres de variables cortos y genéricos, que se pueden rellenar en el entorno global. Es más seguro a) incluir todas las variables en la definición de función b) no asignar valores predeterminados. Por ejemplo, escriba f = función (a, b), más bien f = función (a = 0, b = NA).


Hay una razón por la que algunos idiomas no permiten variables globales: pueden conducir fácilmente a códigos rotos.

Las reglas de alcance en R le permiten escribir código de manera perezosa: permitir que las funciones usen variables en otros entornos puede ahorrarle algo de escritura, y es ideal para jugar en casos simples.

Sin embargo, si está haciendo algo remotamente complicado, le recomiendo que pase una función a todas las variables que necesita (o, al menos, tenga un control de seguridad completo para tener una alternativa en caso de que las variables no existan) .

En el ejemplo anterior:

La mejor práctica es usar fn1.

Alternativamente, intente algo como

fn3 <- function(x) { if(!exists("a", envir=.GlobalEnv)) { warning("Variable ''a'' does not exist in the global environment") a <- 1 } if(!exists("b", envir=.GlobalEnv)) { warning("Variable ''b'' does not exist in the global environment") b <- 2 } x + a + b }


Si sé que voy a necesitar una función parametrizada por algunos valores y llamada repetidamente, evito los globales utilizando un cierre:

make.fn2 <- function(a, b) { fn2 <- function(x) { return( x + a + b ) } return( fn2 ) } a <- 2; b <- 3 fn2.1 <- make.fn2(a, b) fn2.1(3) # 8 fn2.1(4) # 9 a <- 4 fn2.2 <- make.fn2(a, b) fn2.2(3) # 10 fn2.1(3) # 8

Esto evita claramente hacer referencia a las variables globales, en lugar de usar el entorno que encierra la función para a y b. La modificación de los elementos globales a y b no produce efectos secundarios no deseados cuando se invocan instancias fn2.