Informatik-Monitor/Ländervergleich/BL_Informatik_Einfuehrungsphase_Skript.R

236 lines
7.0 KiB
R

# 0. Pakete laden (ggf. vorher installieren)
# install.packages(c("ggtext","shadowtext","viridis","showtext","sf", "ggplot2", "dplyr", "rnaturalearth", "rnaturalearthhires"))
install.packages("ggnewscale")
library(sf)
library(ggplot2)
library(ggtext)
library(dplyr)
library(rnaturalearth)
library(rnaturalearthhires)
library(showtext)
library(viridis)
library(shadowtext)
library(ggnewscale)
# Variablen
hintergrundfarbe <- "#f2f2f2"
# 1 Automatisches Laden von Schriftarten und Fira Sans aktivieren
showtext_auto()
font_add(family = "Fira Sans", regular = "FiraSans-Regular.ttf")
# 2. Geodaten für Deutschland laden
germany_states <- ne_states(country = "Germany", returnclass = "sf")
# 3. CSV-Daten einlesen
inf_einf <- read.csv2("~/Informatik-Monitor/Ländervergleich/BL_Informatik_Einfuehrungsphase_Schularten.csv", stringsAsFactors = FALSE)
#colnames(schulsystem_daten) <- c("name", "schulsystem")
# -------------------------------------------------------------
# 2) Bestimme pro Bundesland, ob "Wahlpflicht" vorhanden ist.
# Wenn ja: IU_Art = "Wahlpflicht", sonst "Pflicht"
# -------------------------------------------------------------
inf_einf_art_gruppiert <- inf_einf %>% # Starte mit deinen Daten
group_by(Bundesland) %>% # Gruppiere nach Bundesland
summarise(
IU_Art = if ("Wahlpflicht" %in% IU_Art) {
"Wahlpflicht"
} else {
"Pflicht"
}
)
# -------------------------------------------------------------
# 3) Verbinde die gewählte IU_Art wieder mit den Originaldaten.
# Dadurch behältst du nur die Zeilen mit der passenden IU_Art.
# -------------------------------------------------------------
inf_einf_art_gruppiert_gesamt <- inf_einf_art_gruppiert %>% # Nimm die priorisierte Liste
left_join(inf_einf, # Füge die Originaldaten an
by = c("Bundesland", "IU_Art")) # Verknüpfe auf beide Spalten
# -------------------------------------------------------------
# 4) Berechne pro Bundesland den niedrigsten IU_Stunden_min-Wert
# NUR aus den Zeilen der gewählten IU_Art.
# -------------------------------------------------------------
inf_einf_art_gruppiert_gesamt_kurz <- inf_einf_art_gruppiert_gesamt %>% # Starte mit dem verknüpften Datensatz
group_by(Bundesland, IU_Art) %>% # Gruppiere wieder
summarise(
IU_Stunden_min = min(IU_Stunden_min), # Berechne den minimalen Wert
.groups = "drop" # Entferne Gruppierung im Ergebnis
)
# # 5) Geodaten mit Einf-Phase-Daten verknüpfen
# germany_data <- germany_states %>%
# left_join(inf_einf, by = c("name" = "Bundesland"))
# 5) Geodaten mit priorisierten Daten verknüpfen
germany_data <- germany_states %>%
left_join(inf_einf_art_gruppiert_gesamt_kurz, by = c("name" = "Bundesland"))
# postal-Kürzel korrigieren: Brandenburg → "BB"
germany_data <- germany_data %>%
mutate(postal = ifelse(name == "Brandenburg", "BB", postal))
# Nur die Grenzen extrahieren (Linien)
grenzen <- germany_data %>%
st_geometry() %>%
st_cast("MULTIPOLYGON") %>%
st_boundary() %>%
st_sf()
germany_data <- germany_data %>%
mutate(
IU_Farbe = paste0(IU_Art, "_", IU_Stunden_min)
)
farben <- c(
"Wahlpflicht_1" = "#fff16f", # helles Gelb
"Wahlpflicht_2" = "#ffe601", # mittelgold
"Wahlpflicht_3" = "#e8d101", # dunkler Gold-/Orangeton
"Pflicht_1" = "#3e609e", # hellblau
"Pflicht_2" = "#0e1f51" # kräftiges Dunkelblau
)
germany_data <- germany_data %>%
mutate(
IU_Farbe = ifelse(
is.na(IU_Stunden_min) | is.na(IU_Art),
NA_character_, # wirklich Character-NA!
paste0(IU_Art, "_", IU_Stunden_min)
)
) %>%
# Jetzt factorisieren OHNE NA-Level:
mutate(
IU_Farbe = forcats::fct_drop( # entfernt NA-Level, falls es noch drin ist
factor(
IU_Farbe,
levels = c(
"Wahlpflicht_1",
"Wahlpflicht_2",
"Wahlpflicht_3",
"Pflicht_1",
"Pflicht_2"
)
)
)
)
# Mittelpunkte der BL-Flächenberechnen
bundesland_labels <- germany_data %>%
mutate(centroid = st_centroid(geometry)) %>%
mutate(
x = st_coordinates(centroid)[, 1],
y = st_coordinates(centroid)[, 2]
) %>%
mutate(
x = ifelse(name == "Brandenburg", x + 0.5, x), # nach Osten
y = ifelse(name == "Brandenburg", y - 0.4, y) # nach Süden
) %>%
mutate(
x = ifelse(name == "Berlin", x + 0.12, x), # nach Osten
y = ifelse(name == "Berlin", y + 0.12, y) # nach Norden
) %>%
mutate(
x = ifelse(name == "Bremen", x + 0.2, x), # nach Osten
y = ifelse(name == "Bremen", y + 0.04, y) # nach Norden
) %>%
mutate(
x = ifelse(name == "Hamburg", x - 0.05, x), # nach Westen
y = ifelse(name == "Hamburg", y - 0.15, y) # nach Süden
)
# 5. Karte erzeugen mit viridis & ggnewscale
karte <- ggplot() +
# Nicht-NA-Flächen mit Farben
geom_sf(
data = filter(germany_data, !is.na(IU_Farbe)),
aes(fill = IU_Farbe),
color = NA
) +
# NA-Flächen extra füllen
geom_sf(
data = filter(germany_data, is.na(IU_Farbe)),
fill = hintergrundfarbe,
color = NA
) +
geom_sf(
data = grenzen,
fill = NA,
color = hintergrundfarbe,
size = 0.3
) +
coord_sf(expand = FALSE) +
geom_shadowtext(
data = bundesland_labels,
aes(x = x, y = y, label = postal),
family = "Fira Sans",
size = 3.5,
color = hintergrundfarbe,
bg.color = "black",
bg.r = 0.05,
check_overlap = TRUE
) +
scale_fill_manual(
values = farben,
name = "Informatik",
labels = c(
"Wahlpflicht_1" = "Wahlpflicht: 1 WS",
"Wahlpflicht_2" = "Wahlpflicht: 2 WS",
"Wahlpflicht_3" = "Wahlpflicht: 3 WS",
"Pflicht_1" = "Pflicht: 1 WS",
"Pflicht_2" = "Pflicht: 2 WS"
)
) +
labs(
title = "Informatikunterricht in der Einführungsphase",
subtitle = "Informatik in der gymnasialen Oberstufe an allgemeinbildenden Schulen, 2025",
caption = "Datenquelle: Informatik-Monitor"
) +
theme_minimal() +
theme(
text = element_text(family = "Fira Sans"),
plot.title = element_text(face = "bold", size = 16),
plot.subtitle = ggtext::element_markdown(size = 12, lineheight = 1.2),
plot.background = element_rect(fill = hintergrundfarbe, color = NA),
panel.background = element_rect(fill = hintergrundfarbe, color = NA),
legend.background = element_rect(fill = hintergrundfarbe, color = NA),
legend.key = element_rect(fill = hintergrundfarbe, color = NA),
panel.grid = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
legend.position = "bottom",
legend.direction = "horizontal",
legend.box.just = "right",
legend.title = element_blank(),
plot.margin = margin(1, 1, 1, 1, unit = "cm"),
plot.caption = element_text(margin = margin(t = 15))
)
# 6. Karte anzeigen
print(karte)
# 7. Karte speichern
ggsave(
filename = "BL_Oberstufe_IU_Einf_Art_Umfang.svg",
plot = karte,
path = "~/Informatik-Monitor/Ländervergleich",
width = 18,
height = 27,
unit = "cm",
device = "svg"
)