R codes for creating the chart:
# Clear R environment:
rm(list = ls())
# Load some R packages:
library(rvest)
library(magrittr)
library(tidyverse)
# Load admission data for Ivy Colleges:
link <- "https://www.ivycoach.com/ivy-league-statistics-by-college/"
admissions <- read_html(link) %>%
html_table(fill = TRUE, header = FALSE)
# Number of Ivy Colleges:
n <- length(admissions)
# Function processes data for each college:
process_college <- function(j) {
admissions[[j]] -> college_j
college_j %>%
slice(1) %>%
as.vector() %>%
str_replace_all("[^a-z|A-Z]", "") %>%
str_replace_all("University", "") -> col_names
col_names[1] -> Univ_Name
col_names[1] <- "Year"
names(college_j) <- col_names
college_j %>%
slice(-1) %>%
mutate(Univ_Name = Univ_Name) -> final_df
return(final_df)
}
# Convert data for data frame:
lapply(1:n, process_college) -> admissions_data
do.call("bind_rows", admissions_data) -> admissions_data
# Function convert to numeric:
convert_to_num1 <- function(x) {
x %>%
str_replace_all("\\.", ",") %>%
str_replace_all(",", "") %>%
as.numeric() %>%
return()
}
# Calculate accept rate:
admissions_data %>%
select(Year, TotalAppsAccepted, TotalAppsReceived, Univ_Name) %>%
mutate(Year = as.numeric(Year), acc_rate = 100*convert_to_num1(TotalAppsAccepted) / convert_to_num1(TotalAppsReceived)) %>%
mutate(Univ_Name = case_when(Univ_Name == "DartmouthCollege" ~ "Dartmouth",
Univ_Name == "ofPennsylvania" ~ "Pennsylvania",
TRUE ~ Univ_Name)) -> df_for_line
# Set colors for ploting:
color_bgr <- "#1d1330"
df_for_line %>%
filter(Year == 2025) %>%
mutate(label = as.character(round(acc_rate, 1))) %>%
mutate(label = case_when(str_detect(label, "\\.") ~ label,
TRUE ~ str_c(label, ".0"))) -> df_2025
df_for_line %>%
filter(Year == 2007) %>%
mutate(label = as.character(round(acc_rate, 1))) %>%
mutate(label = case_when(str_detect(label, "\\.") ~ label,
TRUE ~ str_c(label, ".0"))) -> df_2007
library(showtext) # -> Package for using extra fonts.
font_subtitle <- "Roboto Condensed" # -> Set Outfit font for our plot.
font_add_google(name = font_subtitle, family = font_subtitle) # -> Load font for using.
font_text <- "Oswald"
font_add_google(name = font_text, family = font_text)
font_main <- "Ubuntu"
font_add_google(name = font_main, family = font_main)
# Automatically render text:
showtext_auto()
x_label <- c("2007", rep("", 17), "2025", rep("", 4))
df_for_line %>%
filter(Year == 2016) %>%
mutate(acc_rate = 3.1) -> df_annotation
p_title <- "Ivy League Acceptance Rates 2007 - 2025"
p_caption <- "Source: IVY COACH | Graphic Designer: Nguyen Chi Dung"
p_subtitle <- "Acceptance rates are decreasing across all Ivy League schools from 2007 to 2025. Harvard is not just\nthe most selective of the Ivies, but it typically ranks as the most selective university in the United States."
df_for_line %>%
ggplot(aes(x = Year, y = acc_rate, group = Univ_Name )) +
geom_area(fill = "cyan", alpha = 0.1) +
geom_line(color = "cyan", size = 0.5) +
geom_point(data = df_2025, shape = 21, size = 2, color = "cyan", fill = "cyan") +
geom_text(data = df_2025, aes(label = label), color = "white",
hjust = -0.3, family = font_subtitle, size = 4, fontface = "bold") +
geom_point(data = df_2007, shape = 21, size = 2, color = "cyan", fill = "cyan") +
geom_text(data = df_2007, aes(label = label), color = "white",
vjust = -1, hjust = 0.2, family = font_subtitle, size = 4, fontface = "bold") +
facet_wrap(~ Univ_Name, nrow = 2, scales = "free_x") +
scale_x_continuous(breaks = seq(2007, 2029, 1), labels = x_label, limits = c(2007, 2029)) +
scale_y_continuous(expand = c(0, 0), limits = c(0, 37)) +
theme(panel.grid.minor.y = element_blank()) +
theme(panel.grid.major.x = element_blank()) +
theme(panel.grid.minor.x = element_blank()) +
theme(axis.title = element_blank()) +
theme(axis.text.y = element_blank()) +
theme(plot.background = element_rect(fill = color_bgr, color = NA)) +
theme(panel.background = element_rect(fill = color_bgr, color = NA)) +
theme(panel.grid = element_blank()) +
theme(axis.ticks = element_blank()) +
geom_hline(yintercept = 0, color = color_bgr, size = 0.7) +
theme(axis.text.x = element_text(family = font_main, color = "white", size = 11)) +
theme(strip.background = element_rect(fill = color_bgr)) +
geom_text(data = df_annotation, aes(label = Univ_Name), color = "white", family = font_main, size = 4, fontface = "bold") +
theme(plot.margin = unit(rep(0.7, 4), "cm")) +
labs(title = p_title, subtitle = p_subtitle, caption = p_caption) +
theme(plot.title = element_text(family = font_main, color = "white", size = 20, face = "bold"),
plot.subtitle = element_text(family = font_main, color = "grey90", size = 11),
plot.caption = element_text(family = font_main, color = "grey70", size = 9, hjust = 0, vjust = -3)) +
theme(plot.title.position = "plot")