R Code for Marginal Effects Plots

library(readxl)
library(tidyverse)
library(patchwork)

# --- Load data ---
file_path <- "C:/Users/Michael/Desktop/Temp One Drive for R/ME Values.xlsx"
principal_data <- read_excel(file_path, sheet = 1)

# --- Clean and prep ---
principal_data$Variable <- trimws(principal_data$Variable)
principal_data$Category <- trimws(principal_data$Category)

# --- Extract base category (e.g., "Crash Characteristics") ---
principal_data <- principal_data %>%
  mutate(CategoryGroup = str_remove(Category, "\\s*\\d+$"))  # remove trailing numbers

# --- Pivot longer ---
plot_long <- principal_data %>%
  pivot_longer(cols = c(KA, BC, O), names_to = "Severity", values_to = "Effect") %>%
  mutate(
    Severity = factor(Severity, levels = c("O", "BC", "KA")),
    Category = factor(Category),  # e.g., "Crash Characteristics 1"
    CategoryGroup = factor(CategoryGroup)  # e.g., "Crash Characteristics"
  )

# --- Colors ---
severity_colors <- c("KA"="#C93312", "BC"="#FDDDA0", "O"="#74A089")

# --- Layout ---
ncol <- 3
categories <- unique(plot_long$Category)
nplots <- length(categories)
nrows <- ceiling(nplots / ncol)
bottom_row_start <- (nrows - 1) * ncol + 1
bottom_row_indices <- bottom_row_start:nplots
bottom_row_indices <- bottom_row_indices[bottom_row_indices <= nplots]

# --- Global y-limits with buffer ---
y_min <- min(plot_long$Effect, na.rm = TRUE)
y_max <- max(plot_long$Effect, na.rm = TRUE)
buffer <- 0.0001 * (y_max - y_min)
y_limits <- c(y_min - buffer, y_max + buffer)

# --- Create plots ---
plot_list <- lapply(seq_along(categories), function(i) {
  cat <- categories[i]
  df <- plot_long %>% filter(Category == cat)
  df$Variable <- factor(df$Variable, levels = rev(unique(df$Variable)))
  
  is_bottom_row <- i %in% bottom_row_indices
  x_lab <- NULL
  y_lab <- if(is_bottom_row) "Marginal Effect" else NULL
  group_title <- unique(df$CategoryGroup)
  
  ggplot(df, aes(x = Variable, y = Effect, fill = Severity)) +
    geom_col(position = position_dodge(width = 0.8), width = 0.8,
             color = "black", size = 0.25) +
    geom_hline(yintercept = 0, linetype = "dashed", color = "black") +
    scale_fill_manual(values = severity_colors) +
    coord_flip() +
    scale_y_continuous(limits = y_limits, expand = c(0, 0)) +
    labs(title = group_title, x = x_lab, y = y_lab) +
    theme_bw(base_size = 10) +
    theme(
      plot.title = element_text(size=18, face="bold", hjust = 0.5),
      axis.title = element_text(size=18, color = "black", face = "bold"),
      axis.text.x = if(is_bottom_row) element_text(size = 16, color = "black") else element_blank(),
      axis.ticks.x = if(is_bottom_row) element_line() else element_blank(),
      axis.text.y = element_text(size = 13, color = "black"),
      legend.position = "none",
      panel.grid.major.y = element_line(color = "gray30"),
      panel.grid.minor.y = element_blank(),
      panel.border = element_blank()
    )
})

# --- Arrange plots dynamically ---
final_plot <- wrap_plots(plot_list, ncol = ncol)
final_plot

# --- Save ---
ggsave("marginal_effect_plots.png", plot = final_plot,
       path = "C:/Users/Michael/OneDrive - Texas State University/NLOGIT6/CRIS/New_Studies/Embankment_Michael/Plots",
       width = 18, height = 12, dpi = 300, bg = "white")