library(shiny) library(DT) library(ggplot2)
ui <- fluidPage( titlePanel(“App Unificada de Amortizaciones”),
sidebarLayout( sidebarPanel( selectInput(“tipo”, “Tipo de amortización:”, choices = c(“Cuotas Constantes (Francés)”, “Amortización Constante”, “Renta Variable (Gradiente Aritmético)”)),
numericInput("capital", "Capital inicial (C):", value = 195000),
numericInput("n", "Número de pagos:", value = 12),
numericInput("tasa", "Tasa de interés anual (%):", value = 12.0),
selectInput("frecuencia", "Capitalización:",
choices = c("Quincenal" = 24, "Mensual" = 12, "Bimestral" = 6,
"Trimestral" = 4, "Semestral" = 2, "Anual" = 1)),
conditionalPanel(
condition = "input.tipo == 'Renta Variable (Gradiente Aritmético)'",
numericInput("R1", "Primer pago (R₁):", value = 50000),
numericInput("d", "Incremento por periodo (d):", value = 6500)
),
conditionalPanel(
condition = "input.tipo == 'Amortización Constante'",
numericInput("R1_ac", "Primer pago (R₁):", value = 24335)
),
actionButton("calcular", "Calcular")
),
mainPanel(
h4("Resultados"),
verbatimTextOutput("renta_text"),
DTOutput("tabla"),
h4("Evolución del Saldo"),
plotOutput("grafico")
)
) )
server <- function(input, output) {
resultados <- eventReactive(input\(calcular, { C <- input\)capital n <- input\(n i <- (input\)tasa / 100) / as.numeric(input\(frecuencia) tipo <- input\)tipo tabla <- data.frame() renta_val <- NA
if (tipo == "Cuotas Constantes (Francés)") {
R <- C * (i / (1 - (1 + i)^(-n)))
saldo <- C
for (t in 1:n) {
interes <- saldo * i
amort <- R - interes
saldo <- saldo - amort
tabla <- rbind(tabla, data.frame(
Periodo = t, Renta = round(R, 2), Interes = round(interes, 2),
Amortizacion = round(amort, 2), Saldo = round(max(saldo, 0), 2)
))
}
renta_val <- R
} else if (tipo == "Amortización Constante") {
A <- C / n
R1 <- input$R1_ac
saldo <- C
for (t in 1:n) {
interes <- saldo * i
renta <- A + interes
saldo <- saldo - A
tabla <- rbind(tabla, data.frame(
Periodo = t, Renta = round(renta, 2), Interes = round(interes, 2),
Amortizacion = round(A, 2), Saldo = round(max(saldo, 0), 2)
))
}
} else if (tipo == "Renta Variable (Gradiente Aritmético)") {
R1 <- input$R1
d <- input$d
T <- (1 - (1 + i)^(-n)) / i
V <- (1 - (1 + n * i) * (1 + i)^(-n)) / (i^2)
VP <- R1 * T + d * V
saldo <- VP
for (t in 1:n) {
R <- R1 + (t - 1) * d
interes <- saldo * i
amort <- R - interes
saldo <- saldo - amort
tabla <- rbind(tabla, data.frame(
Periodo = t, Renta = round(R, 2), Interes = round(interes, 2),
Amortizacion = round(amort, 2), Saldo = round(max(saldo, 0), 2)
))
}
renta_val <- NA
}
list(tabla = tabla, renta_val = renta_val)
})
output\(renta_text <- renderText({ res <- resultados() if (!is.null(res\)renta_val)) { paste0(“Renta constante: \(", format(round(res\)renta_val, 2), nsmall = 2)) } else {”Renta variable.” } })
output\(tabla <- renderDT({ datatable(resultados()\)tabla, options = list(pageLength = 15)) })
output\(grafico <- renderPlot({ res <- resultados() ggplot(res\)tabla, aes(x = Periodo, y = Saldo)) + geom_line(color = “steelblue”, size = 1.2) + geom_point(color = “darkblue”) + theme_minimal() + labs(title = “Evolución del Saldo Insoluto”, y = “Saldo”, x = “Periodo”) }) }
shinyApp(ui = ui, server = server)