Capítulo25 Funciones
El tema proviene de los siguientes sitios.
English: https://r4ds.had.co.nz/functions.html
Español: https://es.r4ds.hadley.nz/funciones.html
Fecha de la última revisión
## [1] "2026-07-29"
25.1 Temas:
- ¿Cuándo escribir una función?
- La anatomía de una función: nombre, argumentos y cuerpo
- Ejecución condicional:
ifyelse - Argumentos y valores por defecto
- Valores de retorno
- Un vistazo a los vectores
En el capítulo de tidyverse avanzado verás funciones más sofisticadas que usan tidy evaluation (el operador
{{ }}). Aquí construimos la base.
25.2 ¿Cuándo escribir una función?
Una función te permite darle un nombre a un bloque de código para poder reutilizarlo. La regla práctica es: si copiaste y pegaste el mismo código más de dos veces, escribe una función. Copiar y pegar es una de las fuentes de errores más comunes, porque es fácil olvidar cambiar el nombre de una variable en una de las copias.
Observa este código que reescala tres columnas para que queden entre 0 y 1:
df <- data.frame(
a = c(2, 5, 8, 1),
b = c(10, 20, 30, 40),
c = c(-5, 0, 5, 10)
)
df$a <- (df$a - min(df$a)) / (max(df$a) - min(df$a))
df$b <- (df$b - min(df$b)) / (max(df$b) - min(df$b))
df$c <- (df$c - min(df$c)) / (max(df$c) - min(df$c))
df## a b c
## 1 0.1428571 0.0000000 0.0000000
## 2 0.5714286 0.3333333 0.3333333
## 3 1.0000000 0.6666667 0.6666667
## 4 0.0000000 1.0000000 1.0000000
¿Notaste el patrón repetido? Eso es una señal clara de que conviene una función.
25.3 La anatomía de una función
Toda función tiene tres partes:
- Un nombre (aquí,
reescalar01). - Los argumentos que van dentro de
function( )(aquí,x). - El cuerpo, el código dentro de las llaves
{ }.
reescalar01 <- function(x) {
rango <- range(x, na.rm = TRUE)
(x - rango[1]) / (rango[2] - rango[1])
}
# Probar la función con un ejemplo cuya respuesta ya conocemos
reescalar01(c(0, 5, 10))## [1] 0.0 0.5 1.0
Ahora el código repetido se reduce a esto, mucho más fácil de leer y de corregir:
df <- data.frame(
a = c(2, 5, 8, 1),
b = c(10, 20, 30, 40),
c = c(-5, 0, 5, 10)
)
df$a <- reescalar01(df$a)
df$b <- reescalar01(df$b)
df$c <- reescalar01(df$c)
df## a b c
## 1 0.1428571 0.0000000 0.0000000
## 2 0.5714286 0.3333333 0.3333333
## 3 1.0000000 0.6666667 0.6666667
## 4 0.0000000 1.0000000 1.0000000
Una función siempre se debe probar con valores cuya respuesta ya conoces antes de confiar en ella.
25.4 Ejecución condicional: if y else
Dentro de una función puedes tomar decisiones con if y else.
signo <- function(x) {
if (x > 0) {
"positivo"
} else if (x < 0) {
"negativo"
} else {
"cero"
}
}
signo(7)## [1] "positivo"
## [1] "negativo"
## [1] "cero"
25.5 Argumentos y valores por defecto
Los argumentos pueden tener un valor por defecto, que se usa cuando quien llama la función no especifica ese argumento.
# Calcular la media recortada; por defecto recorta un 10%
media_recortada <- function(x, recorte = 0.1) {
mean(x, trim = recorte, na.rm = TRUE)
}
valores <- c(1, 2, 3, 4, 5, 100) # el 100 es un valor atípico
media_recortada(valores) # usa recorte = 0.1## [1] 19.16667
## [1] 3.5
## [1] 19.16667
25.6 Valores de retorno
Una función en R devuelve el valor de la última línea de su cuerpo. También
puedes usar return() para devolver un valor antes del final, por ejemplo para
salir temprano en un caso especial.
coef_variacion <- function(x) {
if (mean(x, na.rm = TRUE) == 0) {
return(NA) # evitar división por cero
}
sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE)
}
coef_variacion(c(2, 4, 4, 4, 5, 5, 7, 9))## [1] 0.427618
## [1] NA
25.7 Un vistazo a los vectores
Las funciones trabajan sobre vectores. Conocer los tipos básicos de vectores atómicos explica muchos “comportamientos raros” de R.
lgl <- c(TRUE, FALSE, NA) # lógico
int <- c(1L, 5L, 10L) # entero
dbl <- c(1.5, 2.7, 3.14) # doble (números reales)
chr <- c("a", "b", "c") # cadena de caracteres
typeof(lgl)## [1] "logical"
## [1] "integer"
## [1] "double"
## [1] "character"
Coerción: cuando mezclas tipos, R convierte todo al tipo “más flexible”.
## [1] "1" "2" "tres"
## [1] 1.0 1.0 2.5
Valores faltantes (NA): casi cualquier operación con NA da NA. Por eso
muchas funciones tienen el argumento na.rm = TRUE.
## [1] NA
## [1] 2.333333
## [1] FALSE FALSE TRUE FALSE
- Ejercicios:
Hacer los ejercicios en la sección 19.2 del libro en español.
- Ejercicios:
Escribe una función fahrenheit_a_celsius() que reciba una temperatura en grados
Fahrenheit y devuelva grados Celsius. La fórmula es \(C = (F - 32) \times 5/9\).
Pruébala con 32 (debe dar 0) y con 212 (debe dar 100).
- Ejercicios:
Hacer los ejercicios en la sección 19.4 del libro en español.