Wahlergebnisse und Alter¶

In [1]:
library(tidyverse)
Warning message in system("timedatectl", intern = TRUE):
“running command 'timedatectl' had status 1”
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──

✔ ggplot2 3.3.5     ✔ purrr   0.3.4
✔ tibble  3.1.6     ✔ dplyr   1.0.8
✔ tidyr   1.2.0     ✔ stringr 1.4.0
✔ readr   2.1.2     ✔ forcats 0.5.1

── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()

In [11]:
theme_set(theme_light())
options(repr.plot.res = 150)
In [2]:
data <- read_tsv("btw2021_wuerzburg_age.tsv")
Rows: 1755 Columns: 8
── Column specification ────────────────────────────────────────────────────────
Delimiter: "\t"
chr (2): Ort, Partei
dbl (5): Durchschnittsalter, Erststimmen, ErststimmenAnteil, Zweitstimmen, Z...
lgl (1): Stadt

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
In [3]:
head(data)
Out[3]:
A tibble: 6 × 8
OrtParteiStadtDurchschnittsalterErststimmenErststimmenAnteilZweitstimmenZweitstimmenAnteil
<chr><chr><lgl><dbl><dbl><dbl><dbl><dbl>
Altertheim Alternative für DeutschlandFALSE44.0001050.07749077
Bergtheim Alternative für DeutschlandFALSE42.4001800.07120253
BieberehrenAlternative für DeutschlandFALSE45.100 470.07742998
Eisingen Alternative für DeutschlandFALSE44.3001380.06442577
Erlabrunn Alternative für DeutschlandFALSE43.500 490.03895072
Estenfeld Alternative für DeutschlandFALSE44.5001970.05392828

Altersverteilung in den Ortschaften¶

In [13]:
data %>% select(Ort, Stadt, Durchschnittsalter) %>% unique %>% ggplot(aes(Stadt, Durchschnittsalter)) + geom_boxplot() + geom_jitter()
Out[13]:

Das Durchschnittsalter auf dem Land liegt etwa zwischen 42.5 und 47.5 das in der Stadt zwischen 37.5 und 46. Unterschiede zwischen einzelnen Orten sind also nicht riesig aber doch erkennbar.

Die jüngsten und die ältesten Ortschaften sind:

In [26]:
data %>% select(Ort, Stadt, Durchschnittsalter) %>% unique %>% slice_min(n=5, Durchschnittsalter)
data %>% select(Ort, Stadt, Durchschnittsalter) %>% unique %>% slice_max(n=5, Durchschnittsalter)
Out[26]:
A tibble: 5 × 3
OrtStadtDurchschnittsalter
<chr><lgl><dbl>
Grombühl TRUE38.0
Altstadt TRUE39.1
Frauenland TRUE41.3
Zellerau TRUE41.8
RottenbauerTRUE42.2
Out[26]:
A tibble: 6 × 3
OrtStadtDurchschnittsalter
<chr><lgl><dbl>
Margetshöchheim FALSE48.0
Markt WinterhausenFALSE47.3
Holzkirchen FALSE47.1
Stadt Röttingen FALSE47.0
Riedenheim FALSE46.6
Stadt Eibelstadt FALSE46.6

Korrelation zwischen Parteien (Zweitstimmen) und Alter¶

In [33]:
data %>%
    ggplot(aes(Durchschnittsalter, ZweitstimmenAnteil, color=Partei)) +
        geom_point() + facet_wrap(~Partei) + theme(legend.position="none")
Out[33]:

Es ist schwer hier etwas zu erkennen, da so viele Parteien mit extrem wenigen Stimmen das Bild füllen. Eine Idee wäre es erstmal nur Datenpunkte von >=1% Stimmanteil zu betrachten.

In [40]:
data %>%
    filter(ZweitstimmenAnteil > 0.01) %>%
    ggplot(aes(Durchschnittsalter, ZweitstimmenAnteil, color=Partei)) +
        geom_smooth(method="lm", color="grey", se=FALSE) +
        geom_point() + facet_wrap(~Partei) + theme(legend.position="none")
`geom_smooth()` using formula 'y ~ x'

Out[40]:

Sowohl bei den Grünen als auch bei der CSU scheint ein Zusammenhang zwischen Alter und Stimmanteil zu bestehen. Allerdings in entgegengesetzte Richtung. Die Gerade dient nur der veranschaulichung. Es wurde nicht geprüft ob ein statistisch signifikanter Zusammenhang besteht.

Es könnte natürlich sein, dass der Unterschied eigentlich nicht auf das Alter sondern auf Stadt vs. Land zurückgeführt werden kann. Dies sehen wir uns mal genauer an.

In [45]:
data %>%
    filter(str_detect(Partei, "90|Union")) %>%
    mutate(Stadt = if_else(Stadt, "Stadt", "Land")) %>%
    ggplot(aes(Durchschnittsalter, ZweitstimmenAnteil, color=Partei)) +
        geom_smooth(method="lm", color="grey", se=FALSE) +
        geom_point() + facet_grid(Partei~Stadt) + theme(legend.position="none")
`geom_smooth()` using formula 'y ~ x'

Out[45]:

Tatsächlich ist kein Alterszusammenhang auf dem Land zu erkennen. In der Stadt bleibt er jedoch erhalten.

Altersgewichtete Stimmen¶

In [51]:
data %>%
    group_by(Partei) %>%
    summarize(altersSchnitt = sum(Durchschnittsalter*Zweitstimmen)/sum(Zweitstimmen), stimmen=sum(Zweitstimmen)) %>%
    filter(!is.na(altersSchnitt)) %>%
    arrange(altersSchnitt)
Out[51]:
A tibble: 26 × 3
ParteialtersSchnittstimmen
<chr><dbl><dbl>
Volt Deutschland 42.79627 670
Partei der Humanisten 42.80841 309
DIE LINKE 42.97140 7025
Marxistisch-Leninistische Partei Deutschlands 43.04074 27
BÜNDNIS 90/DIE GRÜNEN 43.0889235635
Partei für Arbeit, Rechtsstaat, Tierschutz, Elitenförderung und basisdemokratische Initiative43.20755 1431
Deutsche Kommunistische Partei 43.31026 39
V-Partei³ - Partei für Veränderung, Vegetarier und Veganer 43.35463 216
Team Todenhöfer – Die Gerechtigkeitspartei 43.51986 433
Die Urbane. Eine HipHop Partei 43.52932 133
Piratenpartei Deutschland 43.53368 665
Bündnis C - Christen für Deutschland 43.53680 125
Freie Demokratische Partei 43.5637719230
Ökologisch-Demokratische Partei 43.67123 1095
PARTEI MENSCH UMWELT TIERSCHUTZ 43.75639 2096
Partei für Gesundheitsforschung 43.75923 233
Basisdemokratische Partei Deutschland 43.80394 2310
Sozialdemokratische Partei Deutschlands 43.8536637078
DER DRITTE WEG 43.91406 64
Alternative für Deutschland 44.0002012217
Christlich-Soziale Union in Bayern e.V. 44.0109355956
FREIE WÄHLER 44.02186 6871
UNABHÄNGIGE für bürgernahe Demokratie 44.03778 405
Liberal-Konservative Reformer 44.21463 41
Bayernpartei 44.22975 279
Nationaldemokratische Partei Deutschlands 44.41316 114

Volt hat also im Schnitt die jüngsten Wähler und die NPD die ältesten. ⚠️ So kann man das nicht sagen. Volt könnte alle Stimmen von 80 jährigen Menschen bekommen haben die in Stadtteilen mit niedrigem Durchschnittsalter leben.

In [0]: