Capítulo26 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-09-02"
26.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.
26.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.
Regla de tres: si copias y pegas el mismo bloque de código más de dos veces, conviértelo en una función. Así reduces errores y solo corriges el código en un lugar.
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.
26.3 La anatomía de una función
R es un lenguaje de programación funcional: las funciones son “ciudadanos de primera clase” (se pueden guardar en variables y pasar a otras funciones). Heredó esta filosofía del lenguaje S y de Scheme, que inspiraron a sus creadores.
function(argumentos) { cuerpo } — crear tu propia función.
- Estructura:
nombre <- function(x) { ... }; se llama luego connombre(valor). - Argumentos: pueden tener valores por defecto (
function(x, recorte = 0.1)). - Retorno: devuelve el último valor evaluado, o el que indiques con
return().
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.
26.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"
26.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
26.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
26.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.
Si olvidas na.rm = TRUE, basta con un solo NA en los datos para que mean(), sd() y muchas otras funciones devuelvan NA sin avisarte. Encontrarás más errores frecuentes y cómo resolverlos en el capítulo Errores comunes (14).
## [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.