Funciones definidas por el usuario

Wed, Jul 22, 2020 5-minute read

En general, una función en R tiene la siguiente estructura:

# nombre_funcion <- function(argumentos){
# Secuencia de comandos que utilizan los argumentos como entradas
# Resultado
# }

Las partes que de una función son:

  • Nombre de la Función. La función quedará almacenada en el ambiente de trabajo de R con este nombre. La función estará disponible para su uso durante la sesión activa.

  • Argumentos. Los argumentos son los valores de entrada que necesita la función para realizar sus operaciones. Aparecen entre paréntesis, separados por comas. Los valores son asignados al nombre del argumento por el usuario cada vez que ejecuta una función. Los argumentos son opcionales. Los argumentos, si existen, pueden tener valores predeterminados.

  • Cuerpo de la función. Este constituye una colección de códigos que definen la tarea de la función.

  • Resultado. Este es el valor que regresa la función. Este es el último enunciado del cuerpo de la función.

Ejemplos

Ejemplo 1

Como primer ejemplo, escribamos una función que calcule el cuadrado de los números en una secuencia. Específicamente, sea aa un número cualquiera. La función imprimirá el cuadrado de la secuencia que va de 1 hasta aa.

secuencia_cuadrados <- function(a) {
   for(i in 1:a) {
      b <- i^2
      print(b)
   }
}
secuencia_cuadrados(5)
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25

También podemos dar un valor predeterminado al argumento de esta función. Por ejemplo, si el usuario no proporciona un valor para aa, la función calcula automáticamente el cuadrado de cada número en la secuencia del 1 al 6.

secuencia_cuadrados <- function(a=6) {
   for(i in 1:a) {
      b <- i^2
      print(b)
   }
}
secuencia_cuadrados()
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25
## [1] 36

Ejemplo 2

Ahora escribimos una función que nos permita dibujar un histograma a partir de cualesquiera datos. Además, las barras de este histograma serán de color azul e indicaremos con líneas la posición de la media y la desviación estándar. La función tendrá un segundo argumento, que será el título de la gráfica generada. Daremos a este el valor predeterminado Histograma.

crear_histograma <- function(datos, nombre="Histograma") {
  media <- mean(datos)
  desv_est <- sd(datos)
  
  hist(datos, main = nombre, xlab = "Datos", ylab = "Frecuencia", col = "blue")
  abline(v = media, col = "red")
  abline(v = media + (desv_est * c(1, -1)), col = "green")
}

Para probar nuestra función, generemos un vector de números aleatorios con alguna media y alguna desviación estándar. Nota que usarmos las funciones predefinidas set.seed(), la cual nos permite que los resultados sean replicables y rnorm().

set.seed(12345)
datos <- rnorm(n = 1500, mean = 15, sd = .75)
crear_histograma(datos)

Ejemplo 3

Un ejemplo más elaborado es el siguiente. Considera la siguiente base de datos que contiene información de 10 estudiantes: 1) género, 2) puntaje en una prueba de lectura, 3) puntaje en una prueba de escritura, 4) puntaje en una prueba de matemáticas y 5) puntaje en una prueba de ciencias. Leemos la base de datos utilizando la función predeterminada read.csv(). Nota que esta puede leer documentos en formato csv ya sea desde el disco duro de tu computadorao bien desde la nube. En este ejemplo estamos leyendo los datos desde Github:

scores <- read.csv("https://raw.githubusercontent.com/amosino/courses--econometria/master/econometria_salud/econometria_salud--datos/HsbData.csv")
scores
##    female read write math science
## 1    male   63    57   55      58
## 2  female   50    49   56      47
## 3  female   50    52   45      58
## 4    male   34    49   39      42
## 5    male   50    59   42      53
## 6  female   76    63   60      67
## 7  female   52    67   57      63
## 8  female   71    65   72      66
## 9    male   60    65   58      61
## 10   male   50    40   39      49

Deseamos calcular el puntaje promedio para cada una de las pruebas aplicadas. Además, para hacer el ejercicio más interesante, el promedio calculado no deberá considerar ni el puntaje más bajo ni el más alto. Por ejemplo, en la columna read deberemos suprimir los datos 34 y 76 antes de calcular la media. El siguiente código hace el trabajo para la columna read, no te preocupes si no comprendes el código en su totalidad:

data <- scores$read
min_max <- c(min(data), max(data))
data_new <- data[!data %in% min_max]
media_recortada <- mean(data_new)
print(media_recortada)
## [1] 55.75

Naturalmente podemos repetir las líneas anteriores para cada una de las columnas para las cuales deseamos calcular la media recortada. Imagina, sin embargo, que tuvieras muchas columnas por calcular. Esto, sin duda, complicaría el trabajo ya que, por una parte, implicaría muchas líneas de código y, por la otra, podría complicar inneceriamente el espacio de trabajo y el número de variables creadas y almacenadas en la memoria de R. Entonces, escribimos una función que calcule la media recortada para cualquier vector que usemos como argumento. Luego usaremos esta para calcular la media recortada de la prueba read o cualquiera otra prueba en la base de datos:

fmedia_recortada <- function(data){
min_max <- c(min(data), max(data))
data_new <- data[!data %in% min_max]
media_recortada <- mean(data_new)
print(media_recortada)
}
fmedia_recortada(scores$read)
## [1] 55.75

Para terminar el trabajo, podemos echar mano del ciclo for, para calcular la media recortada de las diferentes pruebas automáticamente. Nota que hemos utilizado la función predeterminada rep() para crear un vector de ceros llamado promedios. Los ceros de este vector serán remplazados por los valores resultantes de los cálculos dentro del ciclo for. Esto no es indispensable, pero es una práctica muy recomendable que aumenta la velocidad de cómputo.

promedios <- rep(0,4)
for (i in 2:5){
  promedios[i-1] <- fmedia_recortada(scores[,i])
}
## [1] 55.75
## [1] 57.375
## [1] 53.28571
## [1] 56.875

Última actualización: 02-09-2020.