2.2. Creación de Funciones

Si tenemos que repetir un código varias veces, es probable que estemos necesitando crear una función. En R hay una forma conveniente de crearla, y es lo que estaremos haciendo en este módulo.

2.2.1. Construcción de una Función

Al finalizar esta sección podrás crear tus propias funciones

La estructura básica de una función es la siguiente:

NOMBRE <- function(arg_1, arg_2, …) {
CUERPO DE LA FUNCIÓN
}

Dónde:

  • el nombre es cualquiera aceptable en la gramática de R,
  • function(…) es el comando R para crear una función,
  • arg son argumentos opcionales para indicar los grupos de datos a los que se aplicará la función (puede indicarse con una x),
  • en el cuerpo de la función se indican las operaciones y funciones del sistema que se aplicarán a los datos y también se indica que ocurrirá con el resultado, usando por ejemplo return.

Función aplicada a uno o más valores de entrada

Los datos para los argumentos de una función pueden ser individuales o un objeto R. A continuación veremos el caso de entrada de un valor y un vector, como argumento para la función.

# crear función F_to_C con argumento temperatura en grados Fahrenheit
# calcula grados Celsius (centígrados)
F_to_C <- function(temp_F) {
  temp_C <- (temp_F - 32) * 5 / 9
  return(temp_C)
}
# entrada de grados Fahrenheit
F_to_C(212)
## [1] 100
# entrada de varios datos en vector
gf <- c(-40, 32, 80, 104, 212)
gc <- F_to_C(gf)

Temperatura en ºC: -40, 0, 26.6666667, 40, 100

Entrada manual de datos

Es posible detener el procesamiento de una función, para que pida la entrada de su argumento. La función readline permite detener el procesamiento y esperar por la entrada de un dato; la entrada se realiza en la consola, y el procesamiento continúa.

F_to_C_manual <- function() {
  temp_F <- as.numeric(readline(prompt="Temperatura en F: "))
  temp_C <- (temp_F - 32) * 5 / 9
  return(temp_C)
}

Si ahora escribimos:

F_to_C_manual( )

en la consola, nos aparecerá el siguiente mensaje:

Temperatura en F:

Luego de entrar un valor, digamos 212, obtenemos:

[1] 100


Home

2.2.2. Aplicación de Funciones Usando sapply y aggregate

Al finalizar esta sección podrás aplicar una función a diversos objetos y agrupar por categorías

Usando función con sapply en un data.frame o matriz

Una función puede requerir más de un argumento para obtener el resultado. Vamos a usar una función que requiere dos argumentos (masa y altura) y aplicarla a un data.frame con los datos individuales. Para aplicar la función al data.frame, utilizaremos la función sapply. El ejemplo consistirá en el cálculo del índice masa corporal (BMI).

# crear la función BMI para el cálculo del índice de masa corporal
BMI <- function(m,a) {
  bmi <- m/a^2
  res <- list(bmi=bmi)
  return(res)
}
# crear un data.frame a partir de dos vectores
# datos de masa corporal, en kg
masa <- c(60, 58, 66, 69)
# datos de altura, en m
alt <- c(1.65, 1.68, 1.8, 1.60)
# data.frame
datos <- data.frame(masa,alt)
# aplicar función BMI con sapply
rBMI <- sapply(datos, FUN = BMI, datos$alt)
# extraer los resultados de BMI y redondear
rBMI <- round(as.vector(rBMI[[1]]),1)

BMI de los individuos: 22, 20.5, 20.4, 27
 

Usando función con aggregate en un data.frame

La función aggregate añade otra funcionalidad a la aplicación de una función: se pueden separar los datos en grupos, mediante el parámetro by. Vamos a crear una función que calcula algunos estadísticos: tamaño de la muestra, promedio, mediana, y desviación estándar. Los datos son de niveles de Ca plasmático, en ratas macho y hembras, tratadas o no con estrógeno.

# leemos los datos de un archivo externo .csv
ca_rata <- read.csv("data/calcio-ratas.csv")
# creamos la función 'stats'
stats <- function(x){
  m <- mean(x)
  md <- median(x)
  n <- length(x)
  s <- sd(x)
  return(c(n=n, Media=m, Mediana=md, DS=s))
}
# utilizamos aggregate para aplicar la función, por sexo y tratamiento
aggdata <- aggregate(ca_rata$caplasma, 
                     by = list(ca_rata$sexo,ca_rata$hormona),
                     FUN = stats)
# agregamos nombres a las columnas
aggdata <- setNames(aggdata, c("Sexo","Hormona",""))
aggdata
##     Sexo Hormona         n     Media   Mediana        DS
## 1 hembra      no  5.000000 14.880000 15.800000  4.136061
## 2  macho      no  5.000000 12.120000 10.900000  4.247588
## 3 hembra      si  5.000000 32.520000 32.300000  4.670867
## 4  macho      si  5.000000 27.780000 27.800000  4.287423