2.5 Funciones

Tanto en el tema previo como a lo largo de los apartados anteriores de este tema, hemos visto que existen multitud de funciones que nos permiten manipular datos en R. Por supuesto, también es posible crear nuestras propias funciones, para lo que utilizaremos la palabra reservada function. Veamos un ejemplo de una función sencilla:

sumprod<-function(x, y) { 
  return ((x+y)/(x*y)) 
} 

Donde se puede ver que hemos definido una función de nombre «sumprod» que tiene dos parámetros de entrada («x» e «y») y devuelve un resultado (con return).

Podemos declarar directamente la función en el terminal de R, o en un script, tal como vimos en el tema anterior. Una vez declarada, se puede utilizar directamente por su nombre:

sumprod(2,3) 
# [1] 0.8333333 

También es posible definir nuevos operadores binarios, asignando el símbolo del operador a utilizar el lugar del nombre de la función

"%@%"<-function(x, y) { 
  return ((x+y)/(x*y)) 
} 

Y luego simplemente utilizamos directamente el nuevo operador para llamar a la función:

2%@%3 
# [1] 0.8333333 

Aunque en los ejemplos anteriores hemos utilizado la posición de los argumentos para que el sistema sepa qué es «x» y qué «y», es posible pasar los parámetros por nombre explícitamente:

sumprod(y=3, x=2) 
# [1] 0.8333333 

También es posible especificar valores por defecto en los parámetros de la función (de forma que si no se proporcionan en el momento de hacer la llamada, se toman de la declaración), por ejemplo:

sumprod<-function(x, y=1) { 
  return ((x+y)/(x*y)) 
} 
 
sumprod(3) 
# [1] 1.333333 

Incluso es posible que esos valores por defecto no sean constantes, sino que se obtengan a partir de otros parámetros:

sumprod<-function(x, y=length(x)) { 
    return ((x+y)/(x*y)) 
} 
 
v<-seq(1,3) 
sumprod(v) 
# [1] 1.3333333 0.8333333 0.6666667 

Podemos utilizar la función missing para comprobar si un determinado parámetro ha sido proporcionado o no a la hora de llamar a nuestra función:

f<-function(x=1, y) { 
  if (missing(y)) { 
    y<-2 
  } 
  return(x+y) 
} 
 
f(2) 
# [1] 4 

f(2,3) 
# [1] 5 

R también nos permite indicar que pueden existir una serie de parámetros adicionales que no son conocidos en el momento de declarar la función. Esto es útil, por ejemplo, cuando desde una función queremos llamar a otra y necesitamos los argumentos de esa segunda función, pero no sabemos cuáles van a ser (pensad en el caso de la funciones apply/lapply/tapply, que vimos en este tema).

Para hacer esto, incluiremos en el listado de parámetros de nuestra función puntos suspensivos (denominados formalmente ellipsis), y accederemos a los valores que ahí se proporcionan como una lista.

Por ejemplo:

f<-function(x, y=2, ...) { 
    args<-list(...)      # Obtenemos la lista de argumentos 
  for (arg in args) {    # Recorremos la lista 
       print(arg) 
  } 
}