Funciones recursivas
Parte de la sección Lógica y flujo del Journey de R de Coddy. Lección 50 de 64.
Una función recursiva se llama a sí misma con una versión más pequeña del problema. Necesita un caso base que devuelva un resultado sin llamarse a sí misma, o nunca se detendría:
fact <- function(n) {
if (n <= 1) return(1)
n * fact(n - 1)
}
print(fact(5))Salida:
[1] 120Cada llamada espera a que termine la llamada más pequeña: fact(3) calcula 3 * fact(2), que calcula 2 * fact(1), que devuelve 1. Cada paso debe avanzar hacia el caso base:
count_down <- function(n) {
if (n == 0) {
cat("go\n")
return(invisible(NULL))
}
cat(n, "")
count_down(n - 1)
}
count_down(3)Salida:
3 2 1 goLa recursión se adapta a datos que contienen copias más pequeñas de sí mismos, como una lista que contiene listas. Esta función suma cada número, sin importar qué tan profundamente esté anidado:
deep_sum <- function(x) {
if (is.numeric(x)) return(sum(x))
total <- 0
for (item in x) total <- total + deep_sum(item)
total
}
print(deep_sum(list(1, list(2, 3), list(list(4)), 5)))Salida:
[1] 15Una llamada recursiva también puede dividir el problema por la mitad. La búsqueda binaria examina el centro de un vector ordenado y continúa en la mitad que puede contener el objetivo:
find <- function(v, target, lo = 1, hi = length(v)) {
if (lo > hi) return(NA)
mid <- (lo + hi) %/% 2
if (v[mid] == target) return(mid)
if (v[mid] < target) find(v, target, mid + 1, hi) else find(v, target, lo, mid - 1)
}
print(find(c(2, 5, 8, 12, 19), 12))
print(find(c(2, 5, 8, 12, 19), 7))Salida:
[1] 4
[1] NADesafío
FácilCompleta count_digits(n) de forma recursiva. Un número menor que 10 tiene 1 dígito; cualquier número mayor tiene un dígito más que n %/% 10. No conviertas el número en texto.
El código proporcionado lee un número entero n (0 o más) e imprime el valor devuelto.
Pruébalo tú mismo
count_digits <- function(n) {
# Escribe tu código aquí
0
}
# Código de entrada/salida suministrado: déjalo como está
input <- suppressWarnings(readLines(file("stdin")))
cat(count_digits(as.numeric(input[1])), sep = "\n")
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Lógica y flujo
1Cadenas a fondo
Subcadenas con substr()Formateo con sprintf()Dividir y unirBuscar cadenasReemplazar textoRepaso - Constructor de nombres de usuario4Matrices
Creación de matricesIndexación de matricesResúmenes de filas y columnasAritmética de matricesRepaso: tabla de asientos10Flujo de control avanzado
La función switch()ifelse() vectorizadorepeat y breakFunciones recursivasRepaso - Clasificador de calificaciones2Búsquedas clave-valor
Búsquedas en vectores con nombreComprobar clavesAñadir y eliminar clavesRecorrer nombresRepaso: panel bursátil5Proyecto - Libro de calificaciones
Añadir estudiantesRegistrar calificaciones3Conjuntos y conteo
Valores únicosOperaciones con conjuntosPruebas de pertenenciaConteo con table()Repaso: invitados al evento6Funciones como valores
Funciones anónimasPasar funcionesDevolver funcionesClausuras con estadoRepaso: reglas de descuento9Marcos de datos
Creación de marcos de datosColumnas y filasFiltrado de filasAdición y ordenaciónRepaso - Informe de ventas12Proyecto: Rastreador de gastos
Registro de gastosGasto totalPractica por tu cuenta: Compilador de R online