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.
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:
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
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
Al finalizar esta sección podrás aplicar una función a diversos objetos y agrupar por categorías
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
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