# 2. User Interface (UI)
# Designing the dashboard layout and input controls
ui <- fluidPage(
titlePanel("Vehicle Defect Trends by Euro Regulations"),
sidebarLayout(
sidebarPanel(
# Switch between brand-level and region-level analysis
radioButtons("analysis_level", "Analysis Level:",
choices = c("By Brand" = "MAKETXT", "By Region" = "Region"),
selected = "MAKETXT",
inline = TRUE),
hr(),
# Filter by manufacturing region
selectizeInput("region", "1. Select Region (Country):",
choices = c("All", "Korea", "Germany", "Japan", "USA", "UK", "Europe/Others"),
multiple = TRUE,
options = list(placeholder = 'Select Region')),
# Dynamic multi-brand selection
selectizeInput("brand", "2. Select Brands to Compare:",
choices = NULL,
multiple = TRUE,
options = list(placeholder = 'Select brands')),
# Filter by specific vehicle component
selectInput("part", "3. Select Component Category:",
choices = c("All Components", "ENGINE", "FUEL SYSTEM", "POWER TRAIN"),
selected = "All Components"),
# Production year range selector
sliderInput("year_range", "4. Select Production Year Range:",
min = 2000, max = 2026,
value = c(2000, 2026),
sep = ""),
hr(),
helpText("Data source: NHTSA Consumer Complaints Dataset")
),
mainPanel(
# Interactive chart output
highchartOutput("trendPlot", height = "500px"),
hr(),
# Statistical analysis output for the essay
h4("Statistical Analysis Results (Linear Regression)"),
verbatimTextOutput("statResults")
)
)
)
# 3. Server Logic
# Handling data processing, filtering, and rendering
server <- function(input, output, session) {
# Update brand dropdown list based on the selected region
observe({
if (is.null(input$region)) {
brand_choices <- character(0)
} else if ("All" %in% input$region) {
brand_choices <- sort(unique(df_final$MAKETXT))
} else {
brand_choices <- df_final %>%
filter(Region %in% input$region) %>%
pull(MAKETXT) %>%
unique() %>%
sort()
}
updateSelectizeInput(session, "brand", choices = brand_choices, server = TRUE)
})
# Reactive function to filter data based on user inputs
filtered_data_react <- reactive({
data <- df_final
# Filter by Region
if (!("All" %in% input$region) && !is.null(input$region)) {
data <- data %>% filter(Region %in% input$region)
}
# Filter by Brand (only if Analysis Level is 'By Brand')
if (input$analysis_level == "MAKETXT" && !is.null(input$brand)) {
data <- data %>% filter(MAKETXT %in% input$brand)
}
# Filter by Component Keyword
if (input$part != "All Components") {
data <- data %>% filter(grepl(input$part, detail, ignore.case = TRUE))
}
# Filter by Year Range selected in the slider
data <- data %>%
filter(!is.na(MODELYEAR) & MODELYEAR != 9999) %>%
filter(MODELYEAR >= input$year_range[1] & MODELYEAR <= input$year_range[2])
data
})
# Render the Interactive Trend Plot
output$trendPlot <- renderHighchart({
if (input$analysis_level == "MAKETXT") req(input$brand)
if (input$analysis_level == "Region") req(input$region)
# Group and summarize defect counts
summary_data <- filtered_data_react() %>%
group_by(MODELYEAR, group_var = .data[[input$analysis_level]]) %>%
summarise(complaints = n(), .groups = "drop")
hchart(summary_data, "line", hcaes(x = MODELYEAR, y = complaints, group = group_var)) %>%
hc_title(text = paste("Yearly Complaints Trend Comparison",
ifelse(input$analysis_level == "MAKETXT", "(By Brand)", "(By Region)"))) %>%
hc_xAxis(
title = list(text = "Production Year"),
# Euro Regulation periods with background colors
plotBands = list(
list(from = 2005, to = 2010, color = "#FFFFF0", label = list(text = "EURO 4")),
list(from = 2011, to = 2014, color = "#E0FFFF", label = list(text = "EURO 5")),
list(from = 2015, to = 2024, color = "#FFE4E1", label = list(text = "EURO 6"))
)
) %>%
hc_yAxis(title = list(text = "Number of Complaints Reported")) %>%
hc_tooltip(shared = TRUE, crosshairs = TRUE)
})
# Perform Linear Regression and display results
output$statResults <- renderPrint({
if (input$analysis_level == "MAKETXT") req(input$brand)
# Aggregate data by year for regression
stat_data <- filtered_data_react() %>%
group_by(MODELYEAR) %>%
summarise(total_complaints = n(), .groups = "drop")
# Calculate Linear Regression Model
fit <- lm(total_complaints ~ MODELYEAR, data = stat_data)
cat("Linear Regression Analysis:\n")
print(summary(fit))
cat("\nRegression Equation:\n")
cat(paste0("Complaints = ", round(coef(fit)[1], 2), " + ", round(coef(fit)[2], 2), " * (Production Year)\n"))
})
}
shinyApp(ui = ui, server = server)