Funciones
## Objetivos de Aprendizaje
- Crear y llamar funciones
- Comprender parámetros y argumentos
- Dominar alcance de funciones
- Trabajar con funciones anónimas
- Manejar argumentos variables
## Definir Funciones
### Función Básica
```r
# Definición de función
saludar <- function() {
print("¡Hola, Mundo!")
}
# Llamar función
saludar()
```
### Función con Parámetros
```r
# Parámetro único
saludar <- function(nombre) {
paste("Hola,", nombre)
}
saludar("Alicia") # "Hola, Alicia"
# Múltiples parámetros
sumar <- function(a, b) {
a + b
}
sumar(3, 5) # 8
```
### Parámetros por Defecto
```r
# Valores por defecto
saludar <- function(nombre = "Mundo") {
paste("Hola,", nombre)
}
saludar() # "Hola, Mundo"
saludar("Alicia") # "Hola, Alicia"
# Múltiples valores por defecto
potencia <- function(base, exp = 2) {
base ^ exp
}
potencia(3) # 9
potencia(3, 3) # 27
```
## Valores de Retorno
### Retorno Explícito
```r
# Usando return()
absoluto <- function(x) {
if (x < 0) {
return(-x)
}
return(x)
}
absoluto(-5) # 5
absoluto(5) # 5
```
### Retorno Implícito
```r
# La última expresión se retorna automáticamente
absoluto <- function(x) {
if (x < 0) -x else x
}
# Error común
obtener_info <- function(x) {
if (x > 0) {
print("positivo") # ¡Retorna NULL!
}
"hecho"
}
```
### Retornar Múltiples Valores
```r
# Retornar como lista
estadisticas <- function(x) {
list(
media = mean(x),
mediana = median(x),
sd = sd(x)
)
}
resultado <- estadisticas(1:10)
resultado$media # 5.5
resultado$mediana # 5.5
```
## Argumentos Nombrados
### Usar Nombres
```r
# Llamar con nombres
potencia(base = 3, exp = 2)
# El orden no importa con nombres
potencia(exp = 2, base = 3)
# Mezclar posicional y nombrado
potencia(3, exp = 2)
```
### Coincidencia Parcial
```r
potencia <- function(base = 2, exponente = 1) {
base ^ exponente
}
potencia(e = 3) # Funciona: e coincide con exponente
```
## Alcance
### Fundamentos de Entorno
```r
# Variables fuera de función son visibles
variable_global <- 10
mi_funcion <- function() {
print(variable_global) # 10
}
mi_funcion()
```
### Variables Locales
```r
mi_funcion <- function() {
variable_local <- 20 # Solo existe dentro de la función
print(variable_local)
}
mi_funcion()
# variable_global # Error: objeto no encontrado
```
### La Asignación Crea Locales
```r
x <- 10
mi_funcion <- function() {
x <- 20 # Crea nueva variable local
print(x) # 20
}
mi_funcion()
print(x) # 10 (sin cambios)
```
### Usar <<- para Asignación Global
```r
x <- 10
mi_funcion <- function() {
x <<- 20 # Modifica variable global
print(x)
}
mi_funcion() # 20
print(x) # 20
```
## Funciones Anónimas
### Funciones sin Nombre
```r
# Función anónima
function(x) x ^ 2
# Asignar a variable
cuadrado <- function(x) x ^ 2
# O usar anónima directamente
(function(x) x ^ 2)(5) # 25
```
### En Funciones Apply
```r
nums <- list(a = 1:3, b = 4:6)
# Anónima en lapply
lapply(nums, function(x) sum(x) / length(x))
# Anónima en sapply
sapply(1:3, function(x) if (x %% 2 == 0) "par" else "impar")
```
## Argumentos Variables
### ... (Elipsis)
```r
# Pasar argumentos
imprimir_todo <- function(...) {
args <- list(...)
for (arg in args) {
print(arg)
}
}
imprimir_todo(1, "hola", TRUE, c(1, 2, 3))
```
### Aplicación Parcial
```r
# Fijar algunos argumentos
potencia <- function(base, exp) {
base ^ exp
}
al_cuadrado <- function(x) potencia(x, 2)
al_cubo <- function(x) potencia(x, 3)
al_cuadrado(5) # 25
al_cubo(5) # 125
```
## Función como Valor de Retorno
### Retornar Funciones
```r
# Fábrica de funciones
hacer_potencia <- function(exp) {
function(x) {
x ^ exp
}
}
al_cuadrado <- hacer_potencia(2)
al_cubo <- hacer_potencia(3)
al_cuadrado(5) # 25
al_cubo(5) # 125
```
## Operadores de Funciones
### Pipe con Funciones
```r
# Pipe nativo de R 4.1+
1:10 |> sum() |> sqrt()
# Estilo antiguo
library(magrittr)
1:10 %>% sum() %>% sqrt()
```
## Clausura
### Capturar Entorno
```r
# Ejemplo de contador usando clausura
hacer_contador <- function() {
conteo <- 0
function() {
conteo <<- conteo + 1
conteo
}
}
contador1 <- hacer_contador()
contador2 <- hacer_contador()
contador1() # 1
contador1() # 2
contador1() # 3
contador2() # 1 (conteo separado)
```
## Funciones Vectorizadas
### Hacer Funciones Vectorizadas
```r
# Tu función solo toma valor único
sumar_uno <- function(x) x + 1
# Vectorizarla
sumar_uno_vectorizada <- Vectorize(sumar_uno)
sumar_uno_vectorizada(1:5) # 2 3 4 5 6
```
## Manejo de Errores
### tryCatch
```r
# Manejo básico de errores
division_segura <- function(a, b) {
tryCatch({
if (b == 0) stop("División por cero")
a / b
},
error = function(e) {
message("Error: ", e$message)
NA
})
}
division_segura(10, 2) # 5
division_segura(10, 0) # NA con mensaje
```
### try para Depuración
```r
# try continúa incluso en error
resultado <- try({
# Código arriesgado
x <- 1:3
y <- c("a", "b")
x + y # ¡Error!
})
if (inherits(resultado, "try-error")) {
print("Operación fallida")
}
```
## Resumen
- Funciones definidas con `function()` y asignadas a variables
- Los parámetros pueden tener valores por defecto
- Usar `return()` para retornos explícitos (o última expresión)
- Usar `list()` para retornar múltiples valores
- Alcance: variables locales sombrean globales
- Usar `<<-` para modificar variables globales
- Funciones anónimas útiles en familia apply
- Usar `...` para argumentos variables
- `Vectorize()` hace que funciones trabajen con vectores
- `tryCatch()` para manejo de errores
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →