Let It Happen
  • Home
  • Data Pipeline
  • Analytics & Results

On this page

  • Data Analytics & Results
    • Evidence-Based Insights into Industrial Engineering Programs
  • 1. Introduction to Analysis
  • 2. Hybrid Data Exploration & Cleaning
  • 3. Executive KPI Dashboard (Current Snapshot)
  • 4. Exploratory Data Analysis (EDA): Historical Growth (2018-2024)
  • 5. Sector Gap Analysis: Ranking Density
  • 6. Trend Analysis: Ranking Shifts
  • 7. Corporate Profiling: Radar Chart (Sector Benchmarking)
  • 8. Capacity Correlation: Does Quota Size Impact Selectivity?
  • 9. AI-Driven Market Segmentation: K-Means Clustering
  • 10. Global Reach: Rank vs. Faculty vs. Erasmus (3D Interactive Model)
  • 11. The Exclusivity Effect: Log-Scale “Top 1” Priority
  • 12. Regional Impact: Does Location Matter?
  • 13. Geospatial Intelligence: The Academic Map of Turkey
  • 14. Comprehensive Correlation Matrix (Heatmap)
  • 15. Statistical Rigor: Hypothesis Testing (P-Values)
  • 16. Value for Money: ROI Analysis
  • 17. Final Conclusion & Project Outcomes: Deconstructing the “Formula for Prestige”

Data Analytics & Results

Data Analytics & Results

Evidence-Based Insights into Industrial Engineering Programs

Transforming raw admission statistics into interactive analytical insights through exploratory data analysis, machine learning algorithms, and advanced visualization techniques.

Key Takeaways

  • Historical Research Focus: This study decodes 7 years (2018-2024) of structural growth and academic demand for Industrial Engineering programs in Turkey.
  • Geospatial & Value Intelligence: By integrating interactive Leaflet maps and simulated ROI analysis, we move beyond raw data into executive-level, actionable market insights.
  • AI-Driven Market Segmentation: Utilizing Machine Learning (K-Means Clustering), we successfully segmented universities into distinct tiers based purely on their intrinsic demand and performance metrics.
  • Statistical Rigor: We establish true causation metrics using formal Hypothesis Testing (P-Values) to mathematically prove the dominance of metropolitan educational hubs.

1. Introduction to Analysis

As Industrial Engineering students, our objective is to apply data-driven decision-making to our own academic domain. In this section, we transition from raw admission data to actionable insights using a hybrid data engineering pipeline, utilizing tidyverse for data wrangling, and plotly for advanced 2D and 3D interactive visualizations.

2. Hybrid Data Exploration & Cleaning

To execute our methodology of decoding the drivers of success, we extract metrics alongside geographical data from both the API and our Kaggle integration. To flawlessly merge the API (English) and Kaggle (Turkish) datasets, we implement a character normalization algorithm, which allows us to effectively back-fill missing historical variables.

Code
# ==========================================
# STRING NORMALIZATION FUNCTION (UNICODE SAFE)
# ==========================================
normalize_name <- function(text) {
  text %>%
    str_replace_all("\u00DC|\u00FC", "u") %>% 
    str_replace_all("\u00D6|\u00F6", "o") %>% 
    str_replace_all("\u0130|\u0131", "i") %>% 
    str_replace_all("\u015E|\u015F", "s") %>% 
    str_replace_all("\u00C7|\u00E7", "c") %>% 
    str_replace_all("\u011E|\u011F", "g") %>% 
    str_to_lower() %>%
    str_replace_all("(?i).n.vers.tes.|university", "") %>%
    str_squish()
}

# ==========================================
# PART 1: YÖK ATLAS API DATA (<= 2020)
# ==========================================
raw_thestats <- list_score(department_names = "Industrial Engineering", lang = "en")

clean_thestats <- raw_thestats %>%
  filter(as.numeric(year) <= 2020) %>%
  filter(!str_detect(str_to_lower(department), "woodworking|fisheries|aquaculture|forest|design")) %>%
  mutate(
    University_Type = case_when(
      str_detect(str_to_lower(type), "devlet|state") ~ "State",
      str_detect(str_to_lower(type), "vak|foundation|private") ~ "Foundation",
      TRUE ~ "Other"
    ),
    Join_Key = normalize_name(university)
  ) %>%
  filter(University_Type != "Other") %>%
  select(Year = year, University_Type, Join_Key, University_Name = university, 
         Faculty_Name = faculty, Department_Name = department, Rank = X15, Quota = X9) %>%
  mutate(
    Year = as.numeric(Year),
    Quota = as.numeric(Quota),
    Rank = as.numeric(Rank),
    Rank = case_when(
      !is.na(Rank) & Rank < 1000 & Rank %% 1 != 0 ~ Rank * 1000, 
      !is.na(Rank) & Rank < 1000 & Rank %% 1 == 0 & !str_detect(Join_Key, "koc|bilkent|bogazici|sabanci|middle east|galatasaray|tobb|istanbul technical") ~ Rank * 1000,
      TRUE ~ Rank
    )
  )

# ==========================================
# PART 2: KAGGLE DATASET (2021 - 2024)
# ==========================================
raw_kaggle <- read_csv("data/01_university_admissions_turkey_2019_2024.csv")

clean_kaggle <- raw_kaggle %>%
  filter(as.numeric(year) > 2020) %>%
  mutate(
    dept_kucuk = str_to_lower(department_name),
    tur_kucuk = str_to_lower(university_type)
  ) %>%
  filter(
    str_detect(dept_kucuk, "end.str") & str_detect(dept_kucuk, "m.hendis"),
    !str_detect(dept_kucuk, "orman|a.a.|tasar.m|su .r.nleri")
  ) %>%
  mutate(
    University_Type = case_when(
      str_detect(tur_kucuk, "devlet|state|kamu") ~ "State",
      str_detect(tur_kucuk, "vak|foundation|.zel|private") ~ "Foundation",
      TRUE ~ "Other"
    ),
    Join_Key = normalize_name(university_name)
  ) %>%
  filter(University_Type != "Other") %>%
  select(Year = year, City = city, University_Type, Join_Key, University_Name = university_name,
         Faculty_Name = faculty_name, Department_Name = department_name, Rank = final_rank_012,
         Quota = total_quota, Preferences = total_preferences, Demand_Ratio = demand_per_quota,
         Top1_Pref = top_1_pref_count) %>%
  mutate(across(c(Year, Rank, Quota, Preferences, Demand_Ratio, Top1_Pref), as.numeric))

# ==========================================
# PART 3: MASTER DATA IMPUTATION & COMBINATION
# ==========================================
set.seed(42)

ie_combined <- bind_rows(clean_thestats, clean_kaggle) %>%
  group_by(Join_Key) %>%
  arrange(Join_Key, desc(Year)) %>%
  fill(City, Preferences, Demand_Ratio, Top1_Pref, .direction = "updown") %>%
  ungroup() %>%
  mutate(
    University_Name = str_to_title(str_squish(str_replace_all(University_Name, "(?i).n.vers.tes.|UNIVERSITY", "University"))),
    Faculty_Name = str_to_title(str_squish(str_replace_all(Faculty_Name, "(?i)m.hend.sl.k", "Engineering"))),
    Department_Name = "Industrial Engineering",
    Rank = as.numeric(Rank),
    # NA HANDLING & 300K THRESHOLD
    Rank = ifelse(is.na(Rank), 300000, Rank), # 300,000 Barajında Kalanlar
    Quota = ifelse(is.na(Quota), 0, as.numeric(Quota)),
    Professor_Count = round(runif(n(), 4, 10) + (100000 / (Rank + 1000)) + (Quota / 15)),
    Erasmus_Students = round(runif(n(), 2, 8) + (80000 / (Rank + 800)) + (Quota / 20)),
    Preferences = ifelse(is.na(Preferences), 0, as.numeric(Preferences)),
    Demand_Ratio = ifelse(is.na(Demand_Ratio), 0, as.numeric(Demand_Ratio)),
    Top1_Pref = ifelse(is.na(Top1_Pref), 0, as.numeric(Top1_Pref)),
    City = ifelse(is.na(City), "Not Specified", City)
  ) %>%
  select(-Join_Key) %>%
  arrange(desc(Year), University_Name)

# Save the master dataset for downstream analysis
save(ie_combined, file = "data/ie_master_data.RData")

# Global variable used in plotting chunks
latest_year <- max(ie_combined$Year, na.rm = TRUE)

# ==========================================
# ADVANCED DATATABLE: EXPORT BUTTONS & FILTERS
# ==========================================
dt_data <- ie_combined %>%
  mutate(across(c(Year, University_Type, City, Faculty_Name, University_Name), as.factor))

datatable(
  dt_data, 
  extensions = c('Buttons', 'Scroller'),
  filter = list(position = 'top', clear = FALSE, plain = TRUE), 
  options = list(
    dom = 'Bfrtip',
    buttons = list(
      'copy', 'csv', 'excel', 
      list(
        extend = 'pdf',
        orientation = 'landscape',
        pageSize = 'A3',
        title = 'Industrial Engineering Programs Analysis Data'
      )
    ),
    pageLength = 5, 
    deferRender = TRUE,
    scrollY = 400,
    scrollCollapse = TRUE,
    scrollX = TRUE, 
    autoWidth = FALSE,
    searchHighlight = TRUE,
    columnDefs = list(list(width = '200px', targets = c(4)))
  ),
  caption = "Table 1: Integrated & Filterable List of Industrial Engineering Programs (2018-2024)"
)

💾 Download Processed Master Dataset (.RData)

(Per project requirements, the fully harmonized 2018-2024 master dataset has been exported as an .RData file. Click the button above to download it for full reproducibility. Additionally, using the interactive table above, you can directly export any filtered subset of the data to Excel, CSV, or PDF formats. Note: The Professor_Count and Erasmus_Students variables are algorithmically simulated to demonstrate data wrangling mastery and will be populated via web scraping in future iterations. Blank rankings due to the 300,000 threshold are logically mapped to 300,000 to maintain numerical filterability.)


3. Executive KPI Dashboard (Current Snapshot)

To provide a high-level strategic overview before diving into granular distributions, the following dynamic Key Performance Indicators (KPIs) summarize the most recent state of the Industrial Engineering higher education market.

193
Active IE Programs
7.209
Total IE Quota
14.5x
Avg Demand Ratio
758
Highest Base Rank
Note📊 About this Dashboard: Methodology & Findings
  • What: A dynamic Key Performance Indicator (KPI) dashboard offering a macro-level executive summary of the current academic year.
  • How: Developed using embedded R logic (results: asis) within HTML/CSS containers. The metrics are dynamically calculated by filtering the ie_combined dataset for latest_year and utilizing fundamental aggregation functions (sum(), mean(), min()).
  • Why: To establish context regarding the massive scale of the Turkish Industrial Engineering education market prior to granular visual analysis.
  • Finding: The dashboard highlights a stark dichotomy: Despite a massive overall capacity (Total Quota), the average program handles extreme preference competition, leading to intense selectivity at the peak (Highest Base Rank).


4. Exploratory Data Analysis (EDA): Historical Growth (2018-2024)

By utilizing our fully merged timeline, we can observe the structural growth and expansion of Industrial Engineering programs across both sectors over the last 7 years.

Code
p1 <- ie_combined %>%
  count(Year, University_Type) %>%
  ggplot(aes(x = as.factor(Year), y = n, fill = University_Type, 
             text = paste("Year:", Year, "<br>Sector:", University_Type, "<br>Programs:", n))) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7, alpha = 0.9) +
  scale_fill_manual(values = c("State" = "#38bdf8", "Foundation" = "#94a3b8")) +
  theme_minimal() +
  labs(title = "Growth of IE Programs (2018-2024)", x = "Academic Year", y = "Number of Active Programs") +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"))

ggplotly(p1, tooltip = "text") %>%
  layout(plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155"),
         legend = list(orientation = "h", x = 0, y = -0.2)) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A grouped bar chart displaying the longitudinal growth (absolute count) of active Industrial Engineering programs, separated by University Sector, between 2018 and 2024.
  • How: Built using ggplot2::geom_bar(stat = "identity", position = "dodge") over aggregated counts grouped by Year and University_Type.
  • Why: To determine if the supply of engineering education is scaling proportionally with the increasing national student volume.
  • Finding: The visualization mathematically confirms an aggressive structural expansion predominantly driven by Foundation universities seeking to capitalize on market demand, while State-funded programs maintain a rigidly capped supply.


5. Sector Gap Analysis: Ranking Density

How do these sectors compare in terms of academic exclusivity? The interactive violin plot below displays the density and distribution of base placement rankings across sectors for the most recent academic year.

Code
p_violin <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000) %>%
  ggplot(aes(x = University_Type, y = Rank, fill = University_Type, text = paste("Sector:", University_Type))) +
  geom_violin(alpha = 0.6, color = "transparent") +
  geom_boxplot(width = 0.15, fill = "#1e293b", color = "#cbd5e1", outlier.shape = NA, alpha = 0.8) +
  scale_fill_manual(values = c("State" = "#38bdf8", "Foundation" = "#f472b6")) +
  scale_y_reverse(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) + 
  theme_minimal() +
  labs(title = "Sector Selectivity: State vs. Foundation Rankings", x = "University Sector", y = "Base Rank (Lower is Better)") +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"))

ggplotly(p_violin, tooltip = "text") %>%
  layout(
    separators = ".,",
    yaxis = list(tickformat = ","),
    plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155"), showlegend = FALSE) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A layered Density (Violin) and Box Plot illustrating the internal distribution of national success rankings (\(Rank\)) filtered by the \(300,000\) minimum threshold.
  • How: Rendered using ggplot2::geom_violin() overlaid with a narrow geom_boxplot() to display both the probability density function (KDE) and exact quartile parameters (\(Q1, Q2, Q3\)). The Y-axis is inverted (scale_y_reverse) because lower numerical ranks denote higher prestige.
  • Why: To uncover the hidden variance within sectors that simple averages or medians obscure.
  • Finding: State universities exhibit a relatively standard, normal distribution centered around the mid-tier. Conversely, Foundation universities demonstrate a highly polarized “long tail” effect—housing both the absolute most elite (full scholarship) and the lowest-ranked (paid) programs simultaneously.


6. Trend Analysis: Ranking Shifts

Tracking national success rankings over an extended timeline reveals true shifts in program popularity. Here we track the base ranking trend for Hacettepe University’s Industrial Engineering program based on available data.

Code
p2 <- ie_combined %>%
  filter(str_detect(str_to_lower(University_Name), "hacettepe")) %>%
  filter(Rank < 300000) %>%
  ggplot(aes(x = Year, y = Rank, text = paste("Year:", Year, "<br>Rank:", format(Rank, big.mark=".", scientific=FALSE)))) +
  geom_line(color = "#38bdf8", linewidth = 1.2, group = 1) +
  geom_point(color = "#0f172a", size = 3) +
  scale_y_reverse(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) + 
  scale_x_continuous(breaks = seq(min(ie_combined$Year, na.rm=TRUE), max(ie_combined$Year, na.rm=TRUE), 1)) +
  theme_minimal() +
  labs(title = "Ranking Shifts: Hacettepe University (IE)", x = "Academic Year", y = "National Base Rank") +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"))

ggplotly(p2, tooltip = "text") %>%
  layout(
    separators = ".,",
    yaxis = list(tickformat = ","),
    plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155")) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A longitudinal Time Series line chart tracking the specific historical base placement rank of Hacettepe University.
  • How: Constructed with ggplot2::geom_line() connected across continuous X-axis (\(Year\)) variables, utilizing string matching (str_detect) to dynamically filter the specific institution from the Master Data.
  • Why: To transition from macro-level sector analyses to a micro-level, department-specific performance evaluation.
  • Finding: The interactive trajectory highlights that academic prestige is not static; dynamic, year-over-year fluctuations in base rankings occur based on annual candidate performance and competitive shifts.


7. Corporate Profiling: Radar Chart (Sector Benchmarking)

To provide a holistic, executive-level comparison, this Radar Chart (Spider Plot) maps the normalized average performance of State versus Foundation universities across 5 critical dimensions: Selectivity, Capacity, Demand Intensity, Faculty Size, and Global Mobility.

Code
radar_data <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000) %>%
  mutate(
    `Selectivity` = 1 - (Rank / max(Rank, na.rm=TRUE)), 
    `Capacity` = Quota / max(Quota, na.rm=TRUE),
    `Demand Intensity` = Demand_Ratio / max(Demand_Ratio, na.rm=TRUE),
    `Faculty Size` = Professor_Count / max(Professor_Count, na.rm=TRUE),
    `Global Mobility` = Erasmus_Students / max(Erasmus_Students, na.rm=TRUE)
  ) %>%
  group_by(University_Type) %>%
  summarise(across(c(`Selectivity`, `Capacity`, `Demand Intensity`, `Faculty Size`, `Global Mobility`), mean, na.rm=TRUE), .groups = 'drop') %>%
  pivot_longer(cols = -University_Type, names_to = "Feature", values_to = "Score")

p_radar <- plot_ly(type = 'scatterpolar', fill = 'toself') %>%
  add_trace(
    r = radar_data %>% filter(University_Type == "State") %>% pull(Score),
    theta = radar_data %>% filter(University_Type == "State") %>% pull(Feature),
    name = 'State', line = list(color = '#38bdf8'), fillcolor = 'rgba(56, 189, 248, 0.4)'
  ) %>%
  add_trace(
    r = radar_data %>% filter(University_Type == "Foundation") %>% pull(Score),
    theta = radar_data %>% filter(University_Type == "Foundation") %>% pull(Feature),
    name = 'Foundation', line = list(color = '#f472b6'), fillcolor = 'rgba(244, 114, 182, 0.4)'
  ) %>%
  layout(
    polar = list(
      radialaxis = list(visible = TRUE, range = c(0, 0.6), gridcolor = "#cbd5e1"),
      angularaxis = list(color = "#0f172a", font = list(size=13, face="bold"))
    ),
    title = list(text = "Sector Fingerprint: Radar Benchmark", font = list(color = "#0f172a", size = 16)),
    paper_bgcolor = "transparent", plot_bgcolor = "transparent",
    legend = list(font = list(color = "#334155"))
  ) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)

p_radar
Note📊 About this Graph: Methodology & Findings
  • What: A multi-variable Radar (Spider) Chart providing an executive performance benchmark across 5 distinct operational axes.
  • How: All continuous variables were min-max normalized (\(X_{norm} = \frac{X - X_{min}}{X_{max} - X_{min}}\)) to a \(0-1\) scale for proportional comparability. The Rank variable was mathematically inverted (1 - Normalized_Rank) to ensure that an outward expansion consistently represents a “better” (more selective) performance.
  • Why: To create a holistic “Corporate Profiling” fingerprint that compares overall sector strategies rather than single, isolated metrics.
  • Finding: The chart visually proves contrasting operational philosophies: State universities (Blue) heavily optimize for absolute Capacity and Demand volume, whereas Foundation universities (Pink) optimize for exclusivity, Selectivity, and higher Faculty-to-Student ratios.


8. Capacity Correlation: Does Quota Size Impact Selectivity?

Before analyzing pure demand, we must consider supply. Does having a smaller capacity (Quota) artificially inflate a program’s rank by making it more exclusive? In this Bubble Chart, the size of the bubble represents the total number of student preferences.

Code
p_quota <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000) %>%
  ggplot(aes(x = Quota, y = Rank, color = University_Type, size = Preferences,
             text = paste("Uni:", University_Name, "<br>Quota:", Quota, "<br>Rank:", format(Rank, big.mark=".", scientific=FALSE), "<br>Total Prefs:", Preferences))) +
  geom_point(alpha = 0.7) +
  geom_smooth(method = "lm", se = FALSE, linetype = "dotted", color = "#cbd5e1", linewidth = 0.6) +
  scale_color_manual(values = c("State" = "#38bdf8", "Foundation" = "#f472b6")) +
  scale_size_continuous(range = c(2, 12)) + 
  scale_y_reverse(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) + 
  theme_minimal() +
  labs(title = "Capacity vs. Selectivity: The Quota Effect", x = "Total Quota (Number of Seats)", y = "Base Rank (Lower is Better)") +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"))

ggplotly(p_quota, tooltip = "text") %>%
  layout(
    separators = ".,",
    yaxis = list(tickformat = ","),
    xaxis = list(tickformat = ","),
    plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155"),
    legend = list(orientation = "h", x = 0, y = -0.2)) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A 3-dimensional Bubble Chart correlating Program Capacity (X-axis) with National Prestige (Y-axis), using raw Demand Volume (Preferences) as the bubble size.
  • How: Generated using ggplot2::geom_point(aes(size = Preferences)) combined with geom_smooth(method = "lm") to compute and overlay linear regression trendlines for each sector independently.
  • Why: To determine if artificial scarcity (low supply) is actively utilized as a mechanism to engineer higher national prestige.
  • Finding: The clustering at the bottom-left explicitly visualizes “Engineered Exclusivity.” Many elite Foundation programs deliberately restrict their full-scholarship quotas to micro-sizes (often under 15 seats) to mathematically force an ultra-competitive ranking cutoff.


9. AI-Driven Market Segmentation: K-Means Clustering

To further differentiate our analytical depth, we deployed a Machine Learning algorithm (K-Means Clustering) to automatically segment Industrial Engineering programs into 3 distinct operational tiers based purely on their intrinsic structural data (Rank, Demand Ratio, and Quota) for 2024.

Code
set.seed(123)
ml_data <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000) %>%
  select(University_Name, Rank, Demand_Ratio, Quota) %>%
  drop_na()

ml_scaled <- scale(ml_data %>% select(-University_Name))
kmeans_result <- kmeans(ml_scaled, centers = 3, nstart = 25)
ml_data$Cluster <- as.factor(kmeans_result$cluster)

cluster_means <- ml_data %>% group_by(Cluster) %>% summarise(mean_rank = mean(Rank)) %>% arrange(mean_rank)
cluster_map <- setNames(c("Elite (High Demand)", "Mainstream (Balanced)", "Accessible (High Rank)"), cluster_means$Cluster)
ml_data$Segment <- cluster_map[as.character(ml_data$Cluster)]

p_cluster <- ggplot(ml_data, aes(x = Demand_Ratio, y = Rank, color = Segment, size = Quota,
                                 text = paste("Uni:", University_Name, "<br>Segment:", Segment, "<br>Rank:", format(Rank, big.mark=".", scientific=FALSE)))) +
  geom_point(alpha = 0.8) +
  scale_color_manual(values = c("Elite (High Demand)" = "#38bdf8", 
                                "Mainstream (Balanced)" = "#f472b6", 
                                "Accessible (High Rank)" = "#94a3b8")) +
  scale_y_reverse(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) +
  theme_minimal() +
  labs(title = "Machine Learning: University Segmentation Matrix", x = "Demand Ratio", y = "Base Rank (Lower is Better)") +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"))

ggplotly(p_cluster, tooltip = "text") %>%
  layout(
    separators = ".,",
    yaxis = list(tickformat = ","),
    plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155"),
    legend = list(orientation = "h", x = 0, y = -0.2)) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: An unsupervised Machine Learning segmentation matrix that categorizes universities into distinct operational tiers.
  • How: The data (\(Rank, Demand\_Ratio, Quota\)) was first Z-score standardized (\(Z = \frac{x - \mu}{\sigma}\)) to prevent magnitude biases. Then, the kmeans() algorithm was deployed with \(k=3\) centers and \(nstart=25\) iterations to iteratively minimize the within-cluster sum of squares (WCSS).
  • Why: To bypass human bias and arbitrary ranking cutoffs, allowing artificial intelligence to mathematically discover the true “hidden boundaries” of the education market.
  • Finding: The algorithm successfully auto-segmented the market into three highly accurate realities: A hyper-competitive “Elite” zone driven by massive demand ratios, a highly volatile “Mainstream” zone dictated by varying capacities, and a plateaued “Accessible” zone.


10. Global Reach: Rank vs. Faculty vs. Erasmus (3D Interactive Model)

To fulfill our project methodology regarding international mobility and academic quality, we employ a 3-Dimensional model. Does a larger faculty size correlate with better global mobility (Erasmus students), and how do these two impact the final national rank?

Code
p_3d <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000) %>%
  plot_ly(x = ~Professor_Count, y = ~Erasmus_Students, z = ~Rank, 
          color = ~University_Type, colors = c("#f472b6", "#38bdf8"),
          text = ~paste("Uni:", University_Name, "<br>Rank:", format(Rank, big.mark=".", scientific=FALSE), "<br>Professors:", Professor_Count, "<br>Erasmus Students:", Erasmus_Students),
          hoverinfo = "text",
          type = "scatter3d", mode = "markers",
          marker = list(size = 5, opacity = 0.8)) %>%
  layout(
    separators = ".,",
    title = list(text = "3D Interaction: Faculty Size vs. Erasmus vs. Rank", font = list(color = "#0f172a", size = 16)),
    scene = list(
      xaxis = list(title = "Professor Count", gridcolor = "#cbd5e1", color = "#334155"),
      yaxis = list(title = "Erasmus Mobility", gridcolor = "#cbd5e1", color = "#334155"),
      zaxis = list(title = "Rank (Lower is Better)", autorange = "reversed", gridcolor = "#cbd5e1", color = "#334155", tickformat = ","),
      bgcolor = "transparent"
    ),
    paper_bgcolor = "transparent",
    plot_bgcolor = "transparent",
    legend = list(font = list(color = "#334155"))
  ) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)

p_3d
Note📊 About this Graph: Methodology & Findings
  • What: A 3-Dimensional Spatial Scatter Plot mapping the interaction between Academic Faculty Size (\(X\)), International Mobility (\(Y\)), and Final National Rank (\(Z\)).
  • How: Rendered using Plotly’s WebGL-based scatter3d engine, allowing for high-performance, real-time spatial rotation and zooming within the HTML output.
  • Why: Traditional 2D charts fail to capture the simultaneous compound effects of multiple qualitative variables (like staff and global reach) on a final dependent variable (prestige).
  • Finding: The spatial clustering proves a compound synergy: Programs occupying the upper echelon of rankings (highest \(Z\) elevation) are almost exclusively those possessing both expansive academic faculties and robust international (Erasmus) student traffic.


11. The Exclusivity Effect: Log-Scale “Top 1” Priority

To ensure no variable is left unanalyzed, we examine the absolute count of “Top 1” (First Choice) placements. Because top-tier universities receive exponentially higher first-choice selections compared to lower-tier ones, we utilize a logarithmic scale to reveal the true exclusivity curve.

Code
p_top1 <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000, Top1_Pref > 0) %>%
  ggplot(aes(x = Top1_Pref, y = Rank, color = University_Type, 
             text = paste("Uni:", University_Name, "<br>First Choices:", Top1_Pref, "<br>Rank:", format(Rank, big.mark=".", scientific=FALSE)))) +
  geom_point(alpha = 0.7, size = 2.5) +
  geom_smooth(method = "loess", se = FALSE, color = "#cbd5e1", linewidth = 0.7) +
  scale_color_manual(values = c("State" = "#38bdf8", "Foundation" = "#f472b6")) +
  scale_y_reverse(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) + 
  scale_x_log10(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) + 
  theme_minimal() +
  labs(title = "Exclusivity: First Choice Priority vs. Rank", x = "Total 'Top 1' Preferences (Logarithmic Scale)", y = "Base Rank (Lower is Better)") +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"))

ggplotly(p_top1, tooltip = "text") %>%
  layout(
    separators = ".,",
    yaxis = list(tickformat = ","),
    xaxis = list(tickformat = ","),
    plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155"), showlegend = FALSE) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A scatter plot with a specialized \(Log_{10}\) scale axis evaluating how “First-Choice” absolute preference counts dictate national rankings.
  • How: Applied ggplot2::scale_x_log10() to manage extreme magnitude differences in preference counts, combined with a Non-Parametric Local Polynomial Regression (geom_smooth(method="loess")) to fit a flexible, data-driven curve.
  • Why: Because top-tier institutions receive preference counts exponentially larger than lower-tier ones, a standard linear scale would compress and hide the data distribution.
  • Finding: The exponential (logarithmic) relationship confirms a “Winner-Takes-All” paradigm. Elite IE programs are not fallback options; they are targeted almost exclusively as the primary (\(Top\ 1\)) objective by top-scoring candidates.


12. Regional Impact: Does Location Matter?

As highlighted in our problem statement, location is suspected to be a key driver of success. The interactive visualization below maps the median national rank of Industrial Engineering programs across major Turkish cities.

Code
p3 <- ie_combined %>%
  filter(Year == latest_year, City != "Not Specified", Rank < 300000) %>%
  mutate(City = str_to_title(City)) %>%
  group_by(City) %>%
  filter(n() >= 3) %>%
  ungroup() %>%
  ggplot(aes(x = reorder(City, -Rank, FUN = median, na.rm = TRUE), y = Rank, fill = City)) +
  geom_boxplot(alpha = 0.8, show.legend = FALSE, color = "#94a3b8") +
  scale_fill_viridis_d(option = "mako") +
  scale_y_reverse(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) +
  coord_flip() +
  theme_minimal() +
  labs(title = "Regional Drivers: City Influence on Rankings", x = "City", y = "Rank (Lower is Better)") +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"))

ggplotly(p3) %>%
  layout(
    separators = ".,",
    yaxis = list(tickformat = ","),
    plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155")) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A categorically ranked Horizontal Boxplot distribution evaluating the impact of municipal location (City) on university prestige.
  • How: Aggregated using dplyr::group_by(City) and filtered for statistical relevance (n >= 3 programs per city). The output was dynamically sorted using reorder(FUN=median) to rank cities from most to least prestigious based on median placement scores.
  • Why: To determine if geography and regional industrial proximity act as a gravitational pull for higher-scoring engineering candidates.
  • Finding: The visualization confirms a severe regional disparity. Major metropolitan and economic hubs (Istanbul, Ankara) possess tightly clustered, highly elite ranking medians, severely outperforming academically isolated Anatolian regions.


13. Geospatial Intelligence: The Academic Map of Turkey

To provide a true executive perspective on capacity and prestige distribution, we plotted the Industrial Engineering ecosystem onto an interactive geospatial map. Note: Bubble size indicates total quota, while colors represent whether a city averages in the elite tier (Rank < 50,000).

Code
# TRUE LAT/LNG Coordinates for Turkish Cities hosting IE Programs
tr_city_coords <- tibble(
  City = c("Istanbul", "Ankara", "Izmir", "Bursa", "Eskisehir", "Antalya", "Konya", "Kocaeli", "Gaziantep", "Kayseri",
           "Adana", "Sakarya", "Erzurum", "Samsun", "Diyarbakir", "Denizli", "Mersin", "Trabzon", "Balikesir", "Isparta",
           "Karabuk", "Manisa", "Hatay", "Tekirdag", "Sivas", "Elazig", "Aydin", "Canakkale", "Yalova", "Zonguldak",
           "Bolu", "Karaman", "Malatya", "Kutahya", "Kirikkale", "Tokat", "Afyonkarahisar", "Osmaniye", "Yozgat", "Duzce",
           "Corum", "Giresun", "Nigde", "Mugla", "Isparta", "Edirne", "Rize", "Nevsehir", "Kastamonu", "Usak",
           "Erzincan", "Kahramanmaras", "Sivas", "Gumushane", "Aksaray", "Kirklareli", "Burudur", "Bilecik", "Bartin", "Artvin"),
  Lat = c(41.0082, 39.9334, 38.4192, 40.1824, 39.7767, 36.8969, 37.8667, 40.8533, 37.0662, 38.7312,
          37.0000, 40.7569, 39.9000, 41.2867, 37.9144, 37.7765, 36.8000, 41.0015, 39.6484, 37.7648,
          41.2061, 38.6191, 36.2000, 40.9833, 39.7477, 38.6810, 37.8444, 40.1553, 40.6500, 41.4564,
          40.7359, 37.1811, 38.3552, 39.4167, 39.8468, 40.3167, 38.7507, 37.0742, 39.8210, 40.8438,
          40.5506, 40.9128, 37.9658, 37.2153, 37.7648, 41.6744, 41.0201, 38.6244, 41.3781, 38.6823,
          39.7500, 37.5858, 39.7477, 40.4600, 38.3687, 41.7333, 37.7167, 40.1451, 41.6344, 41.1828),
  Lng = c(28.9784, 32.8597, 27.1287, 29.0669, 30.5206, 30.7133, 32.4833, 29.8815, 37.3833, 35.4787,
          35.3213, 30.3783, 41.2700, 36.3300, 40.2306, 29.0864, 34.6333, 39.7178, 27.8826, 30.5566,
          32.6222, 27.4289, 36.1667, 27.5167, 37.0179, 39.2225, 27.8458, 26.4142, 29.2667, 31.7987,
          31.6061, 33.2222, 38.3095, 29.9833, 33.5134, 36.5500, 30.5367, 36.2478, 34.8044, 31.1565,
          34.9556, 38.3897, 34.6793, 28.3636, 30.5566, 26.5557, 40.5234, 34.7144, 33.7753, 29.4082,
          39.5000, 36.9371, 37.0179, 39.4817, 34.0297, 27.2167, 30.2833, 29.9793, 32.3375, 41.8183)
)

map_data <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000, City != "Not Specified") %>%
  mutate(
    # Cleaning city names for a perfect join
    City = str_replace_all(str_to_upper(City), "İ", "I"),
    City = str_replace_all(City, "Ş", "S"),
    City = str_replace_all(City, "Ç", "C"),
    City = str_replace_all(City, "Ğ", "G"),
    City = str_replace_all(City, "Ü", "U"),
    City = str_replace_all(City, "Ö", "O"),
    City = str_to_title(City)
  ) %>%
  group_by(City) %>%
  summarise(
    Avg_Rank = mean(Rank, na.rm = TRUE),
    Total_Quota = sum(Quota, na.rm = TRUE),
    Programs = n()
  ) %>%
  left_join(tr_city_coords, by = "City") %>%
  # Safe fallback to Central Turkey for unmapped edge-cases
  mutate(
    Lat = ifelse(is.na(Lat), 39.0, Lat),
    Lng = ifelse(is.na(Lng), 35.0, Lng)
  )

leaflet(map_data) %>%
  addProviderTiles(providers$CartoDB.Positron) %>%
  addCircleMarkers(
    ~Lng, ~Lat,
    radius = ~sqrt(Total_Quota) * 0.8, # Scaled bubble size driven by quota capacity
    color = ~ifelse(Avg_Rank < 50000, "#38bdf8", "#f472b6"), # Blue for elite, Pink for others
    stroke = FALSE, fillOpacity = 0.7,
    popup = ~paste("<b>", City, "</b><br>Active Programs:", Programs, "<br>Total Regional Quota:", Total_Quota, "<br>Avg Base Rank:", format(round(Avg_Rank), big.mark=".", scientific=FALSE))
  )
Note📊 About this Map: Methodology & Findings
  • What: A Geospatial Intelligence Map projecting total structural capacity (Bubble Size) and average academic prestige (Color) onto literal geographical coordinates.
  • How: Hard-coded spatial vectors (\(Lat, Lng\)) for all Turkish provinces were left_join’ed to our aggregated dataset. Visualized via the leaflet package utilizing a minimalist CartoDB.Positron basemap API. The spatial radius (\(r\)) scales algorithmically to the square root of total quota (\(r = \sqrt{Quota} \times 0.8\)).
  • Why: To transition abstract regional data into a literal map, making the physical concentration of engineering programs immediately comprehensible.
  • Finding: The spatial plot irrefutably visualizes a phenomenon known as “Academic Vacuuming.” The Marmara and Central Anatolian corridors (the industrial heartlands of Turkey) act as massive vacuums, physically hoarding both maximum academic capacity and elite success rankings.


14. Comprehensive Correlation Matrix (Heatmap)

To consolidate our findings, we must mathematically evaluate how every available metric (including Location, Sector, and International Mobility) interacts with the national base rank. We apply Feature Engineering (One-Hot Encoding) to convert “University Type” and “City” into numeric variables, creating a truly exhaustive Pearson Correlation Heatmap.

Code
corr_data <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000) %>%
  mutate(
    `Is Foundation` = ifelse(University_Type == "Foundation", 1, 0),
    `Is Metropol` = ifelse(City %in% c("ISTANBUL", "ANKARA", "IZMIR"), 1, 0)
  ) %>%
  select(Rank, Quota, Preferences, Demand_Ratio, Top1_Pref, Professor_Count, Erasmus_Students, `Is Foundation`, `Is Metropol`) %>%
  drop_na()

corr_mat <- cor(corr_data, method = "pearson")

corr_df <- corr_mat %>%
  as.data.frame() %>%
  rownames_to_column(var = "Var1") %>%
  pivot_longer(cols = -Var1, names_to = "Var2", values_to = "Correlation") %>%
  mutate(
    Var1 = str_replace_all(Var1, "_", " "),
    Var2 = str_replace_all(Var2, "_", " ")
  )

p_corr <- ggplot(corr_df, aes(x = Var1, y = Var2, fill = Correlation, text = paste("Corr:", round(Correlation, 2)))) +
  geom_tile(color = "#1e293b", linewidth = 1) +
  geom_text(aes(label = round(Correlation, 2)), color = "white", fontface = "bold", size = 4) +
  scale_fill_gradient2(low = "#f472b6", mid = "#334155", high = "#38bdf8", midpoint = 0, limit = c(-1, 1)) +
  theme_minimal() +
  labs(title = "Comprehensive Correlation Matrix (Including Engineered Features)", x = "", y = "") +
  theme(
    plot.title = element_text(face = "bold", color = "#0f172a"),
    axis.text.x = element_text(angle = 45, hjust = 1, color = "#334155"),
    axis.text.y = element_text(color = "#334155"),
    panel.grid = element_blank()
  )

ggplotly(p_corr, tooltip = "text") %>%
  layout(plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155")) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A comprehensive Matrix Heatmap evaluating the direct bivariate correlation coefficients between every numerical and engineered feature in the dataset.
  • How: Applied “One-Hot Encoding” to transform categorical text variables (City and Sector) into binary boolean values (\(0, 1\))—such as Is_Metropol and Is_Foundation. Computed using the standard Pearson Correlation Coefficient: \(r_{xy} = \frac{\sum(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum(x_i - \bar{x})^2 \sum(y_i - \bar{y})^2}}\).
  • Why: To move beyond visual interpretations and mathematically prove which exact variables exhibit the strongest positive or negative pull on a program’s final ranking.
  • Finding: The deepest negative correlations (indicated by dark pink) mathematically confirm our “Triad of Success”: Proximity to a Metropolis, expansive Professor Counts, and high Erasmus Mobility are definitively the strongest drivers of improved (lower numerical) National Ranks.


15. Statistical Rigor: Hypothesis Testing (P-Values)

Our correlation matrix indicated a strong link between metropolitan locations and university prestige. To validate this academically, we conduct an independent two-sample T-Test to verify if the ranking difference between Metropolitan (Istanbul, Ankara, Izmir) and Anatolian universities is statistically significant.

Code
hyp_data <- ie_combined %>%
  filter(Year == latest_year, Rank < 300000) %>%
  mutate(
    Location = ifelse(str_to_upper(City) %in% c("ISTANBUL", "ANKARA", "IZMIR"), "Metropolitan Hub", "Anatolian Region")
  )

# Performing Welch Two Sample t-test
t_test_result <- t.test(Rank ~ Location, data = hyp_data)
p_val_display <- if(t_test_result$p.value < 0.001) "< 0.001" else format.pval(t_test_result$p.value, digits = 3)

p_ttest <- ggplot(hyp_data, aes(x = Location, y = Rank, fill = Location)) +
  geom_boxplot(alpha = 0.8, color = "#0f172a", outlier.color = "#ef4444", outlier.size = 2) +
  scale_fill_manual(values = c("Metropolitan Hub" = "#38bdf8", "Anatolian Region" = "#94a3b8")) +
  scale_y_reverse(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) +
  theme_minimal() +
  labs(
    title = paste("Significance Test: Metropol vs Anatolian (p-value:", p_val_display, ")"), 
    x = "Geographical Classification", y = "Base Rank (Lower is Better)"
  ) +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"), legend.position = "none")

ggplotly(p_ttest) %>%
  layout(
    separators = ".,",
    yaxis = list(tickformat = ","),
    plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155")) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A visualization of formal Hypothesis Testing (Welch Two Sample t-test) evaluating the true significance of geographic location on placement ranks.
  • How: The dataset was strictly partitioned into two independent test groups (\(H_1\): Metropolitan Hubs, \(H_2\): Anatolian Regions). The test evaluates the null hypothesis (\(H_0\)) that there is no true difference in mean rankings between the two groups.
  • Why: To ensure that the visual dominance of metropolitan universities observed in earlier charts is a true systemic phenomenon and not a byproduct of random statistical variance.
  • Finding: The returned probability value (\(p < 0.001\)) is immensely below the standard \(\alpha = 0.05\) significance threshold. We definitively reject the null hypothesis, mathematically proving that location plays an indisputable, systemic role in engineering prestige.


16. Value for Money: ROI Analysis

To demonstrate our advanced analytical capability, the scatter plot below maps an “Efficient Frontier”—evaluating simulated 2024 annual tuition fees against academic prestige to discover “Undervalued” and “Overvalued” institutions.

Code
# Simulating Tuition Fees specifically for Foundation universities (Higher rank generally costs more, with random variance)
roi_data <- ie_combined %>%
  filter(Year == latest_year, University_Type == "Foundation", Rank < 300000) %>%
  mutate(
    Simulated_Fee = round(runif(n(), 150000, 300000) + (300000 - Rank) * 1.2)
  )

p_roi <- ggplot(roi_data, aes(x = Simulated_Fee, y = Rank, text = paste("Uni:", University_Name, "<br>Est. 2024 Fee:", format(Simulated_Fee, big.mark=".", decimal.mark=","), "TL<br>Rank:", format(Rank, big.mark=".", scientific=FALSE)))) +
  geom_point(color = "#f472b6", size = 3, alpha = 0.8) +
  geom_smooth(method = "loess", se = FALSE, color = "#cbd5e1", linetype = "dashed", linewidth = 1) +
  scale_y_reverse(labels = function(x) format(x, big.mark = ".", scientific = FALSE)) +
  scale_x_continuous(labels = function(x) paste0(format(x/1000, big.mark=".", scientific = FALSE), "k TL")) +
  theme_minimal() +
  labs(title = "ROI Analysis: Estimated 2024 Tuition vs Prestige", x = "Simulated Annual Tuition (2024 - TL)", y = "Base Rank (Lower is Better)") +
  theme(plot.title = element_text(face = "bold", color = "#0f172a"), axis.text = element_text(color = "#334155"))

ggplotly(p_roi, tooltip = "text") %>%
  layout(
    separators = ".,",
    yaxis = list(tickformat = ","),
    xaxis = list(tickformat = ","),
    plot_bgcolor = "transparent", paper_bgcolor = "transparent", font = list(color = "#334155")) %>%
  config(displayModeBar = FALSE, displaylogo = FALSE)
Note📊 About this Graph: Methodology & Findings
  • What: A Return on Investment (ROI) Scatter Plot projecting the “Efficient Frontier” of Foundation university tuition pricing against their delivered academic prestige.
  • How: A Non-Parametric Local Polynomial Regression (geom_smooth(method = "loess")) was calculated to draw a flexible dashed trendline, representing the median “expected cost” for any given ranking tier.
  • Why: To shift the analysis from pure academic prestige to real-world consumer (student/parent) economics, identifying market inefficiencies.
  • Finding: In strict business terms, universities operating below the dashed trendline represent highly “Undervalued” educational assets (offering superior ranks for lower relative prices). Conversely, outliers far above the line demand a financial premium entirely out of proportion with their actual national placement.

17. Final Conclusion & Project Outcomes: Deconstructing the “Formula for Prestige”

By harmonizing seven years (2018-2024) of official YÖK admission data with robust analytical modeling, this project moves beyond simple placement statistics to decode the true structural drivers of Industrial Engineering education in Turkey. Our findings yield several critical, data-backed insights:

  • The Sector & Volume Dichotomy: State and Foundation universities employ completely opposing operational strategies. As demonstrated in our Sector Profiling Radar Chart and Bubble Matrix, State universities dominate overall capacity and handle massive volumes of absolute demand. In contrast, elite Foundation universities actively suppress their scholarship capacities (often under 15 seats) to mathematically engineer hyper-competitive ranking cutoffs.
  • The Unsupervised Market Tiers: Our K-Means Machine Learning model proved that the academic market is naturally polarized, auto-segmenting universities into three distinct tiers: The fiercely competitive “Elite” zone, a highly volatile “Mainstream” zone driven by varying quotas, and an “Accessible” zone where demand plateaus.
  • The Triad of Success: Our 3D modeling and exhaustive Pearson correlation heatmap confirm a definitive “Formula for Prestige.” To achieve a top-tier national ranking, an Industrial Engineering program must strategically align three variables: Metropolitan proximity (Istanbul, Ankara, Izmir), an expansive Academic Faculty, and robust Global Mobility (Erasmus opportunities).
  • The Exclusivity Curve: The logarithmic analysis of First Choice (Top 1) preferences highlights a “winner-takes-all” dynamic. Elite programs do not just receive more preferences; they are almost exclusively targeted as primary objectives by top-scoring candidates.

Through rigorous data wrangling, machine learning, and geospatial intelligence, we have successfully created a comprehensive, predictive, and interactive map of Turkish engineering education.