Branş-spesific sonuçları görmek için Outputs sayfasına;
Merak edenler kodları görmek isterse de GitHub sayfasına gidebilirsiniz.
Veriler ÖSYM sayfasından .pdf dosyası olarak alınıp, R yazılımı ile düzenlenmiştir.
Veri seti ile ilgili farklı bir değerlendirme isterseniz Twitter üzerinden ya da iletişim formu ile ulaşabilirsiniz. Örn: Kurum spesific veriler.
Yabancı Uyruklu kontenjanları verilere dahil edilmemiştir.
Onlar için de ayrı bir figüre hazırlanabilir.
Verilerde hata varsa muhtemel ÖSYM pdf dosyası ya da kod kaynaklıdır.
R Codes
Import libraries
library(tidyverse)
library(pdftools)
library(glue)
library(ggtext)
my_greens <- c("#13bf13", "#009900")
my_grays <- c("#C0C0C0", "#909090", "#696969")
my_reds <- c("#ff6666")
my_white <- c("#E8E8E8")
my_black <- c("#000000")
Import dataset from ÖSYM link
#
# kadro_tus <- pdftools::pdf_text(pdf = here::here("datasets", "minmax17112023.pdf")) %>%
# as_tibble()
kadro_tus <- pdftools::pdf_text(pdf = here::here("datasets", "Minmax TS2YD Oct 10 2025.pdf")) %>%
as_tibble()
Clean dataset
## Kontenjan tablosu (KKTC kadrolarını görmek için)
#
kontenjan_tus <- pdftools::pdf_text(pdf = here::here("datasets", "Kont Tablo Aug 15 2025.pdf")) %>%
as_tibble()
pattern <- "^(.*(?:Hastanesi|Fakültesi|Komutanlığı))\\s*(.+)$"
kıbrıs_kadroları <- kontenjan_tus %>%
separate_rows(value, sep = "\n") %>%
mutate(value = str_squish(value)) %>%
filter(value != "") %>%
filter(str_detect(value, c("Burhan Nalbantoğlu|Sağlık Bakanlığı|Üniversite"))) |>
# mutate(value = str_remove_all(value, " dipnot \\d")) %>%
# filter(!str_detect(value, "Kontenjan|2025-TUS")) %>%
extract(value, into = c("kurum", "b"), pattern) |>
mutate(kurum = str_replace(kurum, regex("(\\bHastanesi)\\b.*$", ignore_case = TRUE), "\\1"),
b = str_trim(str_replace_all(b, regex("\\bdipnot\\s*\\d+\\b", ignore_case = TRUE), ""))) |>
filter(str_detect(kurum, "KKTC")) |>
slice(1:(n() - 2)) |>
mutate(kurum = str_replace(kurum, "^.*KKTC\\s*", ""),
kurum = str_replace(kurum, "^.*(?=T\\.C\\.)", ""),
b = str_replace(b, "\\s+\\d+$", ""))
## FAILED
kadro_tus_init <- kadro_tus %>%
separate_rows(value, sep = "\n") %>%
mutate(value = str_squish(value)) %>%
filter(value != "") %>%
mutate(value = str_remove_all(value, " dipnot \\d")) %>%
filter(!str_detect(value, "Kontenjan|2025-TUS")) %>%
extract(value, into = c("kurum", "b"), "(.*)/(.*)") %>%
extract(b, into = c("brans", "tur", "d"), "(.*)(Yabancı Uyruklu|Genel)(.*)") %>%
mutate(
d = str_trim(d),
brans = str_trim(brans)
) %>%
separate(d, into = c("kontenjan", "yerlesen", "bos", "min", "max"), sep = " ") %>%
separate(kurum, into = c("number", "kurum"), sep = "^\\d+\\s") %>%
select(-number) %>%
filter(tur == "Genel") |>
mutate(
kurum = str_replace_all(kurum, "Sağlık Bilimleri Üniversitesi", "SBÜ"),
kurum = str_replace_all(kurum, "Eğitim ve Araştırma Hastanesi", "EAH"),
kurum = str_replace_all(kurum, "Tıp Fakültesi", "Tıp F."),
kurum = str_remove_all(kurum, " \\(ANKARA\\)"),
yerlesen = str_remove_all(yerlesen, "\\*")
) %>%
mutate(across(min:max, ~ if_else(. == "--", NA_character_, .))) %>%
mutate(across(min:max, ~ str_replace_all(., ",", "."))) %>%
mutate(across(kontenjan:max, ~ as.numeric(.))) %>%
mutate(across(min:max, ~ round(., 2))) |>
mutate(nrow = row_number())
# clean_tus_2025 |>
# count(kurum, brans) |>
# filter(n > 1)
#
# kıbrıs_kurumlar_to_delete <- kıbrıs_kadroları |>
# filter(!str_detect(kurum, "Burhan Nalbantoğlu"))
BN_kadro <- kadro_tus_init |> ## Kıbrıs Burhan Nalbantoğlu kadroları
filter(str_detect(kurum, "Burhan Nalbantoğlu")) |>
pull(nrow)
rows_to_delete <- kadro_tus_init |> ## Kıbrıs kadroları
group_by(kurum, brans) |>
mutate(n = n()) |>
filter(n == 2) |>
slice(2) |>
pull(nrow)
clean_tus_2025 <- kadro_tus_init %>%
filter(!nrow %in% rows_to_delete) |>
filter(!nrow %in% BN_kadro) |>
filter(!str_detect(kurum, "Jandarma Genel Komutanlığı")) |>
mutate(
min = if_else(is.na(min), 0, min),
doluluk = 100 * round(yerlesen / kontenjan, 2),
kurum_title = if_else(!str_detect(kurum, "SBÜ|EAH"), str_to_title(kurum), kurum),
equal_kucuk_puan = if_else(min != max, min, NA_real_),
kurum_title = str_remove_all(kurum_title, "Tayfur Ata Sökmen "),
kurum_title = str_remove_all(kurum_title, "Prof. Dr. ")
)
## to TEST
clean_branch_2025 <- clean_tus_2025 %>%
filter(
brans == "PLASTİK, REKONSTRÜKTİF VE ESTETİK CERRAHİ"
) %>%
group_by(kurum) %>%
arrange(desc(kontenjan)) %>%
slice(1) %>%
ungroup()
Define a function to plot for a specific BRANCH
func_tus <- function(my_branch) {
clean_branch_2025 <- clean_tus_2025 %>%
# filter(brans != "ASKERİ SAĞLIK HİZMETLERİ") %>% # There is no position
# filter(brans != "HAVA VE UZAY HEKİMLİĞİ") %>% # There is no position
filter(
# tur == "Genel", # There are some errors in yabancı uyruklu-genel data in the dataset
brans == {{ my_branch }}
) %>%
group_by(kurum) %>% # because of the errors, I chose only higher number of position as "GENEL" and ignored the other
arrange(desc(kontenjan)) %>%
slice(1) %>%
ungroup()
minmax_branch <- clean_branch_2025 %>%
filter(min != 0) %>%
summarise(
min = min(min, na.rm = TRUE),
max = max(max, na.rm = TRUE)
)
doluluk_branch <- clean_branch_2025 %>%
summarise(
sum_kontenjan = sum(kontenjan, na.rm = TRUE),
sum_yerlesen = sum(yerlesen, na.rm = TRUE)
) %>%
mutate(doluluk = paste0("%", round(100 * sum_yerlesen / sum_kontenjan, 1)))
lowest <- clean_branch_2025 %>%
filter(min != 0) %>%
arrange(min) %>%
slice_head() %>%
pull(kurum_title)
highest <- clean_branch_2025 %>%
filter(min != 0) %>%
arrange(desc(max)) %>%
slice_head() %>%
pull(kurum_title)
my_subtitle <- glue::glue("Doluluk: {doluluk_branch$doluluk} ({doluluk_branch$sum_yerlesen}/{doluluk_branch$sum_kontenjan})<br><br>
En yüksek: **{highest}** ({minmax_branch$max})<br><br>
En düşük: {lowest} ({minmax_branch$min})")
branch_plot <- clean_branch_2025 %>%
mutate(
color = case_when(
doluluk >= 100 ~ my_greens[2],
doluluk == 0 ~ my_reds[1],
TRUE ~ my_grays[2]
),
name = glue::glue("<i style='color:{color}'>{kurum_title}</i> ({yerlesen}\\/{kontenjan})"),
name = fct_reorder(name, min)
) %>%
ggplot(aes(x = min, y = name, fill = color)) +
geom_segment(aes(x = min, xend = max, y = name, yend = name), color = my_grays[3]) +
geom_point(aes(x = min, y = name), color = ifelse(clean_branch_2025$doluluk >= 100, my_greens[1], my_grays[1]), size = 2.5) +
geom_point(aes(x = max, y = name), color = ifelse(clean_branch_2025$doluluk >= 100, my_greens[2], my_grays[2]), size = 3.5) +
theme_light() +
scale_x_continuous(limits = c(minmax_branch$min - 2, minmax_branch$max + 2), breaks = seq(45, 80, 5)) +
geom_text(aes(x = max, y = name, label = max),
hjust = -.5, size = 3,
color = ifelse(clean_branch_2025$doluluk >= 100, my_greens[2], my_grays[2])
) +
geom_text(aes(x = equal_kucuk_puan, y = name, label = equal_kucuk_puan), hjust = 1.5, size = 2.5, color = ifelse(clean_branch_2025$doluluk >= 100, my_greens[1], my_grays[2]), check_overlap = TRUE) +
labs(
title = glue:::glue("TUS 2025/II, <span style='color: #95568F;'>{my_branch}</span>"),
subtitle = my_subtitle,
x = "Puan",
y = "",
caption = "<i style='color:#009900'>Yeşil</i> : Kadrolar tam dolu<br><i style='color:#ff6666'>Kırmızı</i>: Kadrolar tam boş<br>kaynak: ÖSYM<br>by @AliGunerMD"
) +
theme(
panel.grid = element_line(color = my_white[1]),
panel.grid.minor.x = element_blank(),
panel.border = element_blank(),
axis.text.y = element_markdown(),
legend.position = "none",
plot.caption = element_markdown(),
plot.title.position = "plot",
plot.title = element_markdown(hjust = .5, size = 14, face = "bold"),
plot.subtitle = element_markdown(hjust = .5)
)
return(branch_plot)
}
use defined function for the BRANCH_NAMES vector
# branch_names <- unique(clean_tus_2025$brans)
branch_names <- clean_tus_2025 %>%
# filter(brans != "ASKERİ SAĞLIK HİZMETLERİ") %>%
# filter(brans != "HAVA VE UZAY HEKİMLİĞİ") %>%
distinct(brans) %>%
pull(brans)
save_ggplot_for_branch <- function(branch_name) {
branch_plot <- func_tus(my_branch = branch_name)
ggsave(branch_plot,
file = file.path("Outputs_2025_2", paste0(branch_name, ".jpg")),
dpi = 300,
width = 9,
height = 14
)
}
purrr::walk(branch_names, save_ggplot_for_branch)
#### To prepare overall BRANCH based image
overall <- clean_tus_2025 |>
# filter(tur == "Genel") |>
# filter(kurum != "Dr. Burhan Nalbantoğlu Devlet Hastanesi") |>
filter(!is.na(brans)) |>
mutate(min = if_else(min == 0, NA_integer_, min)) |>
group_by(kurum, brans) %>% # because of the errors, I chose only higher number of position as "GENEL" and ignored the other
arrange(desc(kontenjan)) %>%
slice(1) %>%
ungroup() |>
summarise(yerl_all = sum(yerlesen, na.rm = TRUE),
kont_all = sum(kontenjan, na.rm = TRUE),
min_all = min(min, na.rm = TRUE),
max_all = max(max, na.rm = TRUE),
.by = brans) |>
mutate(max_all = if_else(yerl_all == 0, 0, max_all),
min_all = if_else(yerl_all == 0, 0, min_all),
doluluk = round(yerl_all * 100 / kont_all, 1)) |>
mutate(label = paste0(brans, " (", yerl_all, "/", kont_all, " - %", doluluk ,")"))
minmax_branch_overall <- overall %>%
filter(min_all != 0) %>%
summarise(
min = min(min_all, na.rm = TRUE),
max = max(max_all, na.rm = TRUE)
)
empty_branches <- overall |>
filter(yerl_all == 0) |>
pull(brans)
branch_plot_overall <- overall |>
mutate(
# brans_corr = str_to_title(brans),
color = case_when(
doluluk >= 100 ~ my_greens[1],
doluluk == 0 ~ my_reds[1],
doluluk >= 90 & doluluk < 100 ~ RforMD:::ag_colors_scale("blue", 12)[12],
doluluk >= 70 & doluluk < 90 ~ RforMD:::ag_colors_scale("blue", 12)[8],
doluluk >= 60 & doluluk < 70 ~ RforMD:::ag_colors_scale("blue", 12)[5],
doluluk > 0 & doluluk < 60 ~ "orange",
TRUE ~ "black"
),
label = glue::glue("<i style='color:{color}'>{label}</i>"),
label = fct_reorder(label, min_all)) |>
ggplot(aes(x = min_all, y = label, color = color)) +
geom_segment(aes(x = min_all, xend = max_all, y = label, yend = label), color = my_grays[3]) +
geom_point(aes(x = min_all, y = label), size = 2.5, color = my_grays[2], ) +
geom_point(aes(x = max_all, y = label), size = 3.5, color = my_greens[2], ) +
theme_light() +
scale_x_continuous(limits = c(minmax_branch_overall$min - 3, minmax_branch_overall$max + 2), breaks = seq(45, 85, 5)) +
geom_text(aes(x = max_all, y = label, label = max_all),
hjust = -.5, size = 3,
color = my_greens[2]
# color = ifelse(overall$doluluk == 100, my_greens[2], my_grays[2])
) +
geom_text(aes(x = min_all, y = label, label = min_all), hjust = 1.5, size = 3,
color = my_grays[3],
check_overlap = TRUE) +
labs(
title = "TUS 2025/II.Dönem Branşların Min-Max puanları ve Doluluk oranları<br>",
subtitle = "",
x = "\nPuan",
y = "",
caption = "Minimum puana göre sıralanmıştır.<br>Dr. Burhan Nalbantoğlu Devlet Hastanesi ve Kıbrıs vatandaşı kadroları çıkarılmıştır.<br>Plastik ve Göz için birer kadroya, aynı puanlı iki aday yerleşmiştir.<br>kaynak: ÖSYM<br>by @AliGunerMD"
) +
theme(
panel.grid = element_line(color = my_white[1]),
panel.grid.minor.x = element_blank(),
panel.border = element_blank(),
axis.text.y = element_markdown(),
legend.position = "none",
plot.caption = element_markdown(),
plot.title.position = "plot",
plot.title = element_markdown(hjust = .5, size = 14, face = "bold"),
plot.subtitle = element_markdown(hjust = .5)
)
ggsave(branch_plot_overall,
file = file.path("branch_plot_overall.jpg"),
dpi = 300,
width = 9,
height = 12
)