library(shiny)
library(ggplot2)
library(DT)
##
## Attaching package: 'DT'
## The following objects are masked from 'package:shiny':
##
## dataTableOutput, renderDataTable
# Mortgage calculator function
mortgage_calculator <- function(loan_amount, interest_rate, loan_term, show_position = NULL) {
# Convert annual interest rate to monthly rate
monthly_rate <- interest_rate / 12
total_payments <- loan_term * 12
# Calculate monthly payment using mortgage formula
monthly_payment <- loan_amount * (monthly_rate * (1 + monthly_rate)^total_payments) /
((1 + monthly_rate)^total_payments - 1)
# Initialize remaining balance array
remaining_balance <- numeric(total_payments)
remaining_balance[1] <- loan_amount
# Simulate mortgage payoff process
for (i in 2:total_payments) {
interest_payment <- remaining_balance[i - 1] * monthly_rate
principal_payment <- monthly_payment - interest_payment
remaining_balance[i] <- max(0, remaining_balance[i - 1] - principal_payment)
if (remaining_balance[i] == 0) break
}
# Calculate total interest paid
total_interest_paid <- sum(monthly_payment * total_payments) - loan_amount
# Prepare results
result <- list(
Initial_Loan_Amount = loan_amount,
Monthly_Payment = round(monthly_payment, 2),
Total_Interest_Paid = round(total_interest_paid, 2),
Remaining_Balance = remaining_balance
)
# Show a subset of remaining balances based on user request
if (!is.null(show_position)) {
if (show_position == "start") {
result$First_10_Months <- head(remaining_balance, 10)
} else if (show_position == "end") {
result$Last_10_Months <- tail(remaining_balance, 10)
}
}
return(result)
}
# UI for the Shiny app
ui <- fluidPage(
titlePanel("Mortgage Calculator"),
# Set light grey background color
tags$style(HTML("body {background-color: #f5f5f5;}")),
sidebarLayout(
sidebarPanel(
numericInput("loan_amount", "Loan Amount ($):", value = 30000, min = 1),
numericInput("interest_rate", "Interest Rate (Annual %):", value = 8, min = 0, max = 100),
numericInput("loan_term", "Loan Term (Years):", value = 25, min = 1),
radioButtons("show_position", "Show Remaining Balance:",
choices = c("None" = NULL, "Start of Loan" = "start", "End of Loan" = "end"),
selected = NULL),
actionButton("calculate", "Calculate"),
actionButton("reset", "Reset"),
br(),
h4("Visualize Your Mortgage Progress!")
),
mainPanel(
# Display mortgage summary
h3("Mortgage Summary"),
verbatimTextOutput("summary_output"),
br(),
# Display remaining balance chart
plotOutput("balance_plot"),
# Show remaining balances for specific months
DT::dataTableOutput("balance_output")
)
)
)
# Server logic for the Shiny app
server <- function(input, output, session) {
# Reactive expression to calculate mortgage details
mortgage_details <- eventReactive(input$calculate, {
mortgage_calculator(
loan_amount = input$loan_amount,
interest_rate = input$interest_rate / 100, # Convert to decimal
loan_term = input$loan_term,
show_position = input$show_position
)
})
# Reset the input fields when the reset button is clicked
observeEvent(input$reset, {
updateNumericInput(session, "loan_amount", value = 30000)
updateNumericInput(session, "interest_rate", value = 8)
updateNumericInput(session, "loan_term", value = 25)
updateRadioButtons(session, "show_position", selected = NULL)
output$summary_output <- renderPrint({""})
output$balance_plot <- renderPlot({NULL})
output$balance_output <- renderDT({NULL})
})
# Display summary of results
output$summary_output <- renderPrint({
details <- mortgage_details()
cat("Initial Loan Amount: $", details$Initial_Loan_Amount, "\n")
cat("Monthly Payment: $", details$Monthly_Payment, "\n")
cat("Total Interest Paid: $", details$Total_Interest_Paid, "\n")
})
# Display remaining balance chart
output$balance_plot <- renderPlot({
details <- mortgage_details()
remaining_balance <- details$Remaining_Balance
# Create a color gradient for the plot based on the remaining balance
color_gradient <- colorRampPalette(c("red", "green"))
ggplot(data.frame(Month = 1:length(remaining_balance), Balance = remaining_balance), aes(x = Month, y = Balance)) +
geom_line(aes(color = Balance), size = 1.5) +
scale_color_gradientn(colors = color_gradient(100)) +
labs(title = "Mortgage Remaining Balance Over Time", x = "Month", y = "Remaining Balance ($)") +
theme_minimal() +
theme(
plot.title = element_text(size = 20, face = "bold"),
axis.title = element_text(size = 14),
axis.text = element_text(size = 12)
)
})
# Display remaining balance details in pages of 10 months each
output$balance_output <- DT::renderDataTable({
details <- mortgage_details()
balance_data <- data.frame(Month = 1:length(details$Remaining_Balance),
Remaining_Balance = details$Remaining_Balance)
# Show the table with pagination, 10 months per page
DT::datatable(balance_data, options = list(
pageLength = 10,
scrollY = "400px",
paging = TRUE
))
})
}
# Run the application
shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents