Vi starter med at indlæse relevante pakker her. Pakkerne er installeret på forhånd hos os, hvorfor vi blot indlæser dem.
library(readxl)
library(data.table)
library(zoo)
library(fixest)
library(plm)
library(lubridate)
library(here)
library(sandwich)
library(lmtest)
library(did)
library(patchwork)
library(tidyverse)
Vores tidsperiode løber fra 1990 til 2024. Startåret er det første hele år efter Berlinmurens fald og markerer dermed begyndelsen på det fælles europæiske politiske landskab, vi undersøger. Slutåret er sat af datadækningen, da vores programmatiske polariseringsmål ikke rækker længere frem.
Vi definerer desuden en udvidet periode fra 1975. Den bruges til kilder, der kun måler ved valg. Kun få lande holdt valg i præcis 1990, og for de øvrige er den seneste måling fra et tidligere år. Holdt et land eksempelvis valg i 1988, føres den værdi frem til 1990 og videre, indtil landet holder valg igen. Uden den udvidede periode ville de første år i panelet stå tomme.
år <- 1990:2024
år_udvidet <- 1975:2024
cat(length(år), "år i analyseperioden og",
length(år_udvidet), "år i den udvidede periode")
35 år i analyseperioden og 50 år i den udvidede periode
Vi afgrænser vores sample i tre trin. Først et institutionelt kriterium, dernæst et regimekriterium og til sidst datadækning.
Første trin omfatter europæiske lande, der i løbet af perioden er eller har været medlemmer af EU eller EFTA. Det giver et udvalg på 32 lande, der består af de nuværende 27 EU-lande, de fire EFTA-lande og Storbritannien.
kandidat_lande <- c("AUT","BEL","BGR","CHE","CYP","CZE","DEU","DNK","ESP","EST",
"FIN","FRA","GBR","GRC","HRV","HUN","IRL","ISL","ITA","LIE",
"LTU","LUX","LVA","MLT","NLD","NOR","POL","PRT","ROU","SVK",
"SVN","SWE")
cat("Antallet af potentielle lande er", length(kandidat_lande))
Antallet af potentielle lande er 32
Andet trin er regimekriteriet. Landene skal ved periodens begyndelse være klassificeret som mindst elektorale demokratier i V-Dems Regimes of the World, hvor 0 og 1 er autokratier, mens 2 og 3 er demokratier. Kriteriet forankres ved periodens begyndelse frem for gennem hele perioden, fordi polarisering kan bidrage til demokratisk tilbagegang. En afgrænsning baseret på hele perioden ville derfor fjerne netop de tilfælde, hvor polariseringen har haft størst betydning.
regime_screening <- read_csv("Data/V-Dem/V-Dem data.csv",
col_select = c(country_text_id, year, v2x_regime)) |>
filter(country_text_id %in% kandidat_lande, year %in% år) |>
rename(lande = country_text_id, år = year, regime = v2x_regime) |>
drop_na(regime) |>
group_by(lande) |>
slice_min(år) |>
ungroup() |>
select(lande, første_år = år, regime) |>
arrange(regime, lande)
cat("Lande med V-Dem-dækning:", nrow(regime_screening), "\n")
Lande med V-Dem-dækning: 31
cat("Uden dækning:", paste(setdiff(kandidat_lande, regime_screening$lande),
collapse = ", "), "\n\n")
Uden dækning: LIE
regime_screening |> filter(regime < 2) |> print()
# A tibble: 2 × 3
lande første_år regime
<chr> <dbl> <dbl>
1 HRV 1991 0
2 SVK 1993 0
Vi kan se, at både Kroatien og Slovakiet var klassificeret som lukkede autokratier. Liechtenstein har ikke dækning i V-Dem og udgår på det tredje kriterium.
lande <- regime_screening |>
filter(regime >= 2) |>
pull(lande) |>
sort()
cat(length(lande), "lande i samplet:", paste(lande, collapse = ", "))
29 lande i samplet: AUT, BEL, BGR, CHE, CYP, CZE, DEU, DNK, ESP, EST, FIN, FRA, GBR, GRC, HUN, IRL, ISL, ITA, LTU, LUX, LVA, MLT, NLD, NOR, POL, PRT, ROU, SVN, SWE
Vi ender således samlet set på 29 lande i samplet.
V-Dem leverer specialets samfundsmæssige polariseringsmål,
v2cacamps, som er eksperters vurdering af, hvor opdelt et
samfund er i fjendtlige politiske lejre. Vi omdøber variablen til
samf_pol i vores script. Hertil indlæser vi to
demokratiindeks, v2x_polyarchy og v2x_libdem,
som vi omdøber til hhv. ele_dem og lib_dem. Vi
sammenligner dem nedenfor og vælger ét af dem som kontrolvariabel i et
robusthedstjek senere. Endelig indlæser vi regimeklassifikationen
v2x_regime, som vi omdøber til regime. Vi
brugte den i afgrænsningen til at se på landenes første år, mens vi her
henter alle år, så vi kan dokumentere, om nogen af landene skifter
regimetype undervejs i perioden. Variablen indgår ikke i nogen
model.
V_Dem <- read_csv("Data/V-Dem/V-Dem data.csv",
col_select = c(country_text_id, year, v2cacamps,
v2x_polyarchy, v2x_libdem, v2x_regime)) |>
filter(country_text_id %in% lande, year %in% år) |>
rename(lande = country_text_id,
år = year,
samf_pol = v2cacamps,
ele_dem = v2x_polyarchy,
lib_dem = v2x_libdem,
regime = v2x_regime)
cat("V-Dem data er indlæst")
V-Dem data er indlæst
Vi undersøger, om nogen af landene skifter regimetype undervejs i perioden.
regimeskift <- V_Dem |>
filter(regime < 2) |>
mutate(kategori = if_else(regime == 0,
"Lukket autokrati",
"Elektoralt autokrati")) |>
group_by(lande, regime, kategori) |>
summarise(antal_år = n(),
år = if (n() == max(år) - min(år) + 1) {
if (n() == 1) as.character(år)
else paste0(min(år), "-", max(år))
} else {
paste(sort(år), collapse = ", ")
},
.groups = "drop") |>
arrange(lande, regime)
if (nrow(regimeskift) == 0) {
cat("Ingen lande er klassificeret som autokratier i perioden")
} else {
print(regimeskift)
}
# A tibble: 2 × 5
lande regime kategori antal_år år
<chr> <dbl> <chr> <int> <chr>
1 EST 1 Elektoralt autokrati 1 1992
2 HUN 1 Elektoralt autokrati 7 2018-2024
Estland (1992) er et enkeltstående år, som formentlig hænger sammen med selvstændigheden i 1991. Ungarn (2018-2024) er derimod et systematisk mønster. Vi beholder begge lande, fordi afgrænsningen er forankret ved periodens begyndelse, og fordi den demokratiske tilbagegang i Ungarn er tæt forbundet med netop den polarisering, vi undersøger.
Nu laver vi en kontrol af vores afgrænsning.
baseline <- V_Dem |>
filter(år == 1990) |>
select(lande, regime)
if (all(baseline$regime >= 2) && nrow(baseline) == length(lande)) {
cat("Alle", nrow(baseline),
"lande er klassificeret som mindst elektorale demokratier i 1990")
} else {
baseline |> filter(regime < 2) |> print()
}
Alle 29 lande er klassificeret som mindst elektorale demokratier i 1990
Vi kontrollerer dimensionerne. 29 lande ganget med 35 år skal give 1015 rækker uden dubletter.
dubletter_V_Dem <- V_Dem |> count(lande, år) |> filter(n > 1)
if (nrow(dubletter_V_Dem) == 0) {
cat(nrow(V_Dem), "rækker,", n_distinct(V_Dem$lande),
"unikke lande og ingen dubletter")
} else {
cat(nrow(V_Dem), "rækker,", n_distinct(V_Dem$lande), "unikke lande\n")
print(dubletter_V_Dem)
}
1015 rækker, 29 unikke lande og ingen dubletter
Vi undersøger dækningen af det samfundsmæssige polariseringsmål pr. land.
V_Dem |>
group_by(lande) |>
summarise(mangler = sum(is.na(samf_pol)),
første_år = min(år[!is.na(samf_pol)])) |>
arrange(desc(mangler)) |>
print(n = 29)
# A tibble: 29 × 3
lande mangler første_år
<chr> <int> <dbl>
1 ISL 10 2000
2 AUT 0 1990
3 BEL 0 1990
4 BGR 0 1990
5 CHE 0 1990
6 CYP 0 1990
7 CZE 0 1990
8 DEU 0 1990
9 DNK 0 1990
10 ESP 0 1990
11 EST 0 1990
12 FIN 0 1990
13 FRA 0 1990
14 GBR 0 1990
15 GRC 0 1990
16 HUN 0 1990
17 IRL 0 1990
18 ITA 0 1990
19 LTU 0 1990
20 LUX 0 1990
21 LVA 0 1990
22 MLT 0 1990
23 NLD 0 1990
24 NOR 0 1990
25 POL 0 1990
26 PRT 0 1990
27 ROU 0 1990
28 SVN 0 1990
29 SWE 0 1990
Island mangler ekspertdækning i tidsperioden 1990-1999 og indgår derfor først fra 2000. Vi har overvejet at lave multiple imputation, men for nu har vi valgt at lade være (foreløbigt valg – drøftes med vejleder).
Nu vil vi teste korrelationen mellem vores to demokratiindeks.
kor_demokrati <- V_Dem |>
group_by(lande) |>
mutate(ele_w = ele_dem - mean(ele_dem, na.rm = TRUE),
lib_w = lib_dem - mean(lib_dem, na.rm = TRUE)) |>
ungroup() |>
summarise(rå = cor(ele_dem, lib_dem, use = "complete.obs"),
within = cor(ele_w, lib_w, use = "complete.obs"))
cat("Rå korrelation: r =", round(kor_demokrati$rå, 2), "\n")
Rå korrelation: r = 0.97
cat("Within-korrelation: r =", round(kor_demokrati$within, 2))
Within-korrelation: r = 0.98
De to demokratiindeks korrelerer 0,97 rå og 0,98 inden for lande. Det skyldes, at det liberale indeks indeholder det elektorale demokratiindeks som komponent. Eftersom vores TWFE-modeller kun bruger variationen inden for landene, ville to separate modeller reelt vise det samme. Vi bruger derfor kun ét af indeksene, og vi vælger det liberale, fordi det er det bredeste af de to.
Manifesto leverer det sekundære polariseringsmål, den programmatiske
polarisering, altså hvor langt partierne står fra hinanden i deres
valgprogrammer. Datasættet har en række pr. parti pr. valg med
højre-venstre-position (rile) og stemmeandel
(pervote). Landenavnene står i klartekst, så vi bygger
først en navnetabel.
manifesto_navne <- c("Austria"="AUT","Belgium"="BEL","Bulgaria"="BGR",
"Switzerland"="CHE","Cyprus"="CYP",
"Czech Republic"="CZE","Germany"="DEU","Denmark"="DNK",
"Spain"="ESP","Estonia"="EST","Finland"="FIN",
"France"="FRA","United Kingdom"="GBR","Greece"="GRC",
"Hungary"="HUN","Ireland"="IRL","Iceland"="ISL",
"Italy"="ITA","Lithuania"="LTU","Luxembourg"="LUX",
"Latvia"="LVA","Malta"="MLT","Netherlands"="NLD",
"Norway"="NOR","Poland"="POL","Portugal"="PRT",
"Romania"="ROU","Slovenia"="SVN","Sweden"="SWE")
cat("Navnetabellen indeholder", length(manifesto_navne), "lande")
Navnetabellen indeholder 29 lande
Vi kontrollerer, at navnetabellen dækker alle lande i samplet.
mangler <- setdiff(lande, manifesto_navne)
if (length(mangler) == 0) {
cat("Navnetabellen dækker alle", length(lande), "lande i samplet")
} else {
cat("FEJL — mangler i navnetabellen:", paste(mangler, collapse = ", "))
}
Navnetabellen dækker alle 29 lande i samplet
Vi indlæser fra 1975, så værdier fra valg før 1990 kan føres frem. Vi udleder valgåret af valgdatoen og frasorterer partier uden rile-kodning, uden stemmeandel eller med en stemmeandel på nul.
Manifesto <- read_excel("Data/Manifesto/Manifesto data.xlsx") |>
mutate(lande = manifesto_navne[countryname],
år = year(edate)) |>
filter(!is.na(lande), år %in% år_udvidet) |>
select(lande, år, edate, rile, pervote) |>
drop_na(rile, pervote) |>
filter(pervote > 0)
cat(n_distinct(Manifesto$lande), "unikke lande og",
nrow(distinct(Manifesto, lande, edate)), "valg")
29 unikke lande og 332 valg
Polariseringen beregnes pr. valg som en stemmeandelsvægtet standardafvigelse af partiernes rile-positioner, hvor store partier vægter mere end små. For et valg med n partier beregnes først hvert partis vægt som dets renormaliserede stemmeandel. Renormaliseringen er nødvendig, fordi de kodede partiers stemmeandele ikke nødvendigvis summer til 100 procent. Resten af stemmerne går til småpartier uden rile-kodning, og vægtene skal summe til 1.
w_i = \frac{v_i}{\sum_{j=1}^{n} v_j}
hvor w_i er parti i’s vægt og v_i er dets stemmeandel
(pervote). Dernæst beregnes det vægtede midtpunkt (\mu), altså tyngdepunktet i
partisystemet.
\mu = \sum_{i=1}^{n} w_i \, r_i
hvor r_i er parti i’s rile-position (rile).
Endelig beregnes polariseringen som den vægtede standardafvigelse
omkring midtpunktet.
P = \sqrt{\textstyle\sum_{i=1}^{n} w_i \, (r_i - \mu)^2}
hvor P er polariseringsmålet, som i
koden hedder prog_pol.
Manifesto_valg <- Manifesto |>
group_by(lande, edate, år) |>
summarise(antal_partier = n(),
mu = sum((pervote / sum(pervote)) * rile),
prog_pol = sqrt(sum((pervote / sum(pervote)) * (rile - mu)^2)),
.groups = "drop")
cat(nrow(Manifesto_valg), "valg med beregnet polarisering")
332 valg med beregnet polarisering
Tallet svarer til antallet af valg i indlæsningen, hvilket bekræfter, at aggregeringen fra partiniveau til valgniveau hverken har mistet eller duplikeret valg.
Nu kigger vi på, hvilke lande som har haft dobbeltvalg.
dobbeltvalg <- Manifesto_valg |> count(lande, år) |> filter(n > 1)
if (nrow(dobbeltvalg) == 0) {
cat("Ingen land-år har mere end ét valg.")
} else {
print(dobbeltvalg)
}
# A tibble: 5 × 3
lande år n
<chr> <dbl> <int>
1 ESP 2019 2
2 GRC 1989 2
3 GRC 2012 2
4 GRC 2015 2
5 IRL 1982 2
Fem land-år har to valg samme år. Vi beholder det givne års sidste valg, da det er dét, som gjaldt fremadrettet.
Manifesto_valg <- Manifesto_valg |>
group_by(lande, år) |>
slice_max(edate) |>
ungroup()
cat(nrow(Manifesto_valg), "land-år efter reduktion (forventet: 332 - 5 = 327)")
327 land-år efter reduktion (forventet: 332 - 5 = 327)
Vi dobbeltjekker ovenstående.
dubletter_M <- Manifesto_valg |> count(lande, år) |> filter(n > 1)
if (nrow(dubletter_M) == 0) {
cat("Ingen dubletter")
} else {
print(dubletter_M)
}
Ingen dubletter
Nu laver vi en manuel test af, hvordan vi beregner polariseringen pr. valg som en stemmeandelsvægtet standardafvigelse af partiernes rile-positioner, hvor store partier vægter mere end små. Vi laver udregningen i hånden, hvorefter vi ser, at vi får det samme med kode. Vi tager GBR (2005) som eksempel, fordi valget kun har tre kodede partier.
GBR (2005) havde følgende tre partier: Labour (rile −3,090; pervote 35,186 pct.), Liberal Democrats (rile 3,212; pervote 22,047 pct.) og Conservatives (rile 14,535; pervote 32,359 pct.).
De tre partiers stemmeandele summer ikke til 100 pct., men til 35,186 + 22,047 + 32,359 = 89,592 pct., fordi resten af stemmerne gik til småpartier uden rile-kodning. Derfor renormaliseres andelene først, så vægtene summer til 1: Labour 35,186/89,592 = 0,3927, Liberal Democrats 22,047/89,592 = 0,2461 og Conservatives 32,359/89,592 = 0,3612. Kontrol: 0,3927 + 0,2461 + 0,3612 = 1,0000.
Dernæst det vægtede midtpunkt (μ): 0,3927·(−3,090) + 0,2461·3,212 + 0,3612·14,535 = 4,83.
Hvert partis afstand til midtpunktet: Labour −3,090 − 4,83 = −7,92; Liberal Democrats 3,212 − 4,83 = −1,62; Conservatives 14,535 − 4,83 = 9,71.
Afstandene kvadreres og vægtes med partiets størrelse: Labour (−7,92)² · 0,3927 = 24,61; Liberal Democrats (−1,62)² · 0,2461 = 0,64; Conservatives (9,71)² · 0,3612 = 34,04.
Summen er 24,61 + 0,64 + 34,04 = 59,30, og kvadratroden fører tallet tilbage til rile-skalaens enheder: √59,30 = 7,70.
kontrol_GBR <- Manifesto_valg |>
filter(lande == "GBR", år == 2005) |>
pull(prog_pol)
cat("prog_pol =", format(kontrol_GBR, digits = 3, nsmall = 2, decimal.mark = ","))
prog_pol = 7,70
Manifesto måler kun ved valg, men vores panel skal have en værdi for hvert eneste år. Danmark har f.eks. et valg i 2015 og igen i 2019, men hvad står der så i årene 2016, 2017 og 2018? Vi laver tre versioner, fordi svaret ikke er entydigt.
Kun valgår: Årene mellem valgene står tomme. Vi bruger kun det, vi faktisk har målt, men mister mange år.
LOCF (last observation carried forward): Sidste valgs værdi føres frem, indtil et nyt valg afløser den. 2016-2018 får altså 2015-værdien. Det svarer til virkeligheden, fordi partiernes programmer er uændrede mellem valgene, men giver en trappeformet serie.
Interpolation: Der trækkes en lige linje mellem to valg, så værdien glider gradvist fra 2015-niveauet til 2019-niveauet. Det giver en jævn serie, men opfinder bevægelser, vi ikke har målt.
En vigtig detalje i koden: Udfyldningen sker på den udvidede periode fra 1975, og først bagefter trimmes til 1990-2024. Rækkefølgen er afgørende, fordi havde vi trimmet først, ville et land med sidste valg i f.eks. 1987 kunne stå tom i f.eks. 1990-1991, da der ikke er nogen værdi at føre frem.
Manifesto_panel <- expand_grid(lande = lande, år = år_udvidet) |>
left_join(Manifesto_valg |> select(lande, år, prog_pol),
by = c("lande", "år")) |>
arrange(lande, år) |>
group_by(lande) |>
mutate(prog_pol_valgår = prog_pol,
prog_pol_locf = zoo::na.locf(prog_pol, na.rm = FALSE),
prog_pol_interp = zoo::na.approx(prog_pol, x = år, na.rm = FALSE)) |>
ungroup() |>
filter(år %in% .env$år) |>
select(-prog_pol)
cat(nrow(Manifesto_panel), "rækker (forventet: 29 lande × 35 år = 1015)")
1015 rækker (forventet: 29 lande × 35 år = 1015)
summary(Manifesto_panel |> select(prog_pol_valgår, prog_pol_locf, prog_pol_interp))
prog_pol_valgår prog_pol_locf prog_pol_interp
Min. : 0.2068 Min. : 0.2068 Min. : 0.2068
1st Qu.: 9.4161 1st Qu.: 9.4123 1st Qu.: 9.6775
Median :13.4500 Median :13.4943 Median :13.4239
Mean :14.4624 Mean :14.4395 Mean :14.4201
3rd Qu.:17.9504 3rd Qu.:18.0235 3rd Qu.:17.8732
Max. :33.2055 Max. :33.2055 Max. :33.2055
NAs :769 NAs :20 NAs :146
De tre versioner har praktisk talt identiske fordelinger. Kun antallet af manglende værdier (NAs) adskiller dem. Udfyldningsmetoden ændrer altså ikke selve målet, men afgør kun, hvilke år der har data. LOCF er analysens hovedversion, fordi den giver den bedste dækning.
Vi undersøger dækningen af det programmatiske polariseringsmål pr. land.
dækning_prog <- Manifesto_panel |>
filter(is.na(prog_pol_locf)) |>
group_by(lande) |>
summarise(mangler = n(),
år = if (n() == max(år) - min(år) + 1) {
if (n() == 1) as.character(år)
else paste0(min(år), "-", max(år))
} else {
paste(sort(år), collapse = ", ")
},
.groups = "drop") |>
arrange(desc(mangler), lande)
cat("Manglende observationer i alt:",
sum(is.na(Manifesto_panel$prog_pol_locf)), "\n\n")
Manglende observationer i alt: 20
if (nrow(dækning_prog) == 0) {
cat("Ingen lande mangler observationer")
} else {
print(dækning_prog)
}
# A tibble: 6 × 3
lande mangler år
<chr> <int> <chr>
1 CYP 6 1990-1995
2 MLT 6 1990-1995
3 LVA 3 1990-1992
4 EST 2 1990-1991
5 LTU 2 1990-1991
6 POL 1 1990
Vi kan se, at der er nogle observationer, som vi mangler. Vi har overvejet at lave multiple imputation, men for nu har vi valgt at lade være (foreløbigt valg – drøftes med vejleder).
World Inequality Database giver os vores ulighedsmål, Gini-koefficienten, som måler hvor ulige indkomsten er fordelt i et land på en skala fra 0 til 1, hvor 0 er fuldstændig lighed.
Vi bruger indkomst efter skat, da det er den indkomst, folk faktisk råder over, og dermed den ulighed, de kan opleve.
Data ligger som separate landefiler. Vi bruger derfor en funktion, der læser én fil ad gangen og med det samme filtrerer ned til de rækker, vi skal bruge, i stedet for at indlæse alt og rydde op bagefter.
wid_navne <- c("AT"="AUT","BE"="BEL","BG"="BGR","CH"="CHE","CY"="CYP",
"CZ"="CZE","DE"="DEU","DK"="DNK","EE"="EST","ES"="ESP",
"FI"="FIN","FR"="FRA","GB"="GBR","GR"="GRC","HU"="HUN",
"IE"="IRL","IS"="ISL","IT"="ITA","LT"="LTU","LU"="LUX",
"LV"="LVA","MT"="MLT","NL"="NLD","NO"="NOR","PL"="POL",
"PT"="PRT","RO"="ROU","SE"="SWE","SI"="SVN")
wid_filer <- file.path("Data/World Inequality Database",
paste0("WID_data_", names(wid_navne), ".csv"))
læs_wid <- function(fil) {
fread(fil, sep = ";",
select = c("country", "variable", "percentile", "year", "value")) |>
as_tibble() |>
filter(variable == "gdiincj992",
percentile == "p0p100",
year %in% .env$år)
}
WID <- map(wid_filer, læs_wid) |>
list_rbind() |>
mutate(lande = wid_navne[country]) |>
select(lande, år = year, gini = value)
cat(nrow(WID), "rækker og", n_distinct(WID$lande), "lande")
1015 rækker og 29 lande
Vi ser på, om vi har manglende observationer.
manglende_WID <- sum(is.na(WID$gini))
cat("Manglende observationer:", manglende_WID)
Manglende observationer: 0
Vi har således ingen manglende observationer i WID.
World Bank giver os de resterende økonomiske variable, som vi skal bruge.
wb_filer <- c(
bnp_vækst = "World Bank data BNP-vækst.csv",
bnp_pc = "World Bank data BNP per capita.csv",
inflation = "World Bank data inflation.csv",
arbejdsløshed = "World Bank data arbejdsløshed.csv",
handel = "World Bank data handel.csv") |>
(\(x) setNames(file.path("Data/World Bank", x), names(x)))()
læs_wb <- function(fil, varnavn) {
read_csv(fil, skip = 4, show_col_types = FALSE,
name_repair = "unique_quiet") |>
filter(`Country Code` %in% lande) |>
select(lande = `Country Code`, matches("^\\d{4}$")) |>
pivot_longer(cols = -lande,
names_to = "år",
values_to = varnavn,
names_transform = as.integer) |>
filter(år %in% .env$år)
}
WB <- imap(wb_filer, læs_wb) |>
reduce(full_join, by = c("lande", "år"))
cat(nrow(WB), "rækker og", n_distinct(WB$lande), "lande")
1015 rækker og 29 lande
Vi ser på, om vi har manglende observationer.
manglende_detaljer <- WB |>
pivot_longer(cols = -c(lande, år),
names_to = "variabel", values_to = "værdi") |>
filter(is.na(værdi)) |>
group_by(variabel, lande) |>
summarise(antal = n(),
år = paste(sort(år), collapse = ", "),
.groups = "drop") |>
arrange(variabel, lande)
if (nrow(manglende_detaljer) == 0) {
cat("Ingen manglende observationer")
} else {
print(manglende_detaljer, n = Inf, width = Inf)
}
# A tibble: 46 × 4
variabel lande antal år
<chr> <chr> <int> <chr>
1 arbejdsløshed AUT 1 1990
2 arbejdsløshed BEL 1 1990
3 arbejdsløshed BGR 1 1990
4 arbejdsløshed CHE 1 1990
5 arbejdsløshed CYP 1 1990
6 arbejdsløshed CZE 1 1990
7 arbejdsløshed DEU 1 1990
8 arbejdsløshed DNK 1 1990
9 arbejdsløshed ESP 1 1990
10 arbejdsløshed EST 1 1990
11 arbejdsløshed FIN 1 1990
12 arbejdsløshed FRA 1 1990
13 arbejdsløshed GBR 1 1990
14 arbejdsløshed GRC 1 1990
15 arbejdsløshed HUN 1 1990
16 arbejdsløshed IRL 1 1990
17 arbejdsløshed ISL 1 1990
18 arbejdsløshed ITA 1 1990
19 arbejdsløshed LTU 1 1990
20 arbejdsløshed LUX 1 1990
21 arbejdsløshed LVA 1 1990
22 arbejdsløshed MLT 1 1990
23 arbejdsløshed NLD 1 1990
24 arbejdsløshed NOR 1 1990
25 arbejdsløshed POL 1 1990
26 arbejdsløshed PRT 1 1990
27 arbejdsløshed ROU 1 1990
28 arbejdsløshed SVN 1 1990
29 arbejdsløshed SWE 1 1990
30 bnp_vækst CZE 1 1990
31 bnp_vækst EST 1 1990
32 bnp_vækst LTU 1 1990
33 bnp_vækst LVA 1 1990
34 bnp_vækst POL 1 1990
35 bnp_vækst ROU 1 1990
36 bnp_vækst SVN 1 1990
37 handel EST 3 1990, 1991, 1992
38 handel HUN 1 1990
39 handel LTU 5 1990, 1991, 1992, 1993, 1994
40 handel LVA 5 1990, 1991, 1992, 1993, 1994
41 handel POL 5 1990, 1991, 1992, 1993, 1994
42 inflation CZE 2 1990, 1991
43 inflation EST 3 1990, 1991, 1992
44 inflation LTU 2 1990, 1991
45 inflation LVA 2 1990, 1991
46 inflation ROU 1 1990
Alle manglende observationer ligger i perioden 1990 til 1994. Arbejdsløshed mangler i 1990 for samtlige lande, mens de øvrige huller er koncentreret i enkelte lande i begyndelsen af perioden.
Vi udfylder ikke hullerne, da modellerne udelader observationerne automatisk (foreløbigt valg – drøftes med vejleder).
Vores kilder samles nu til ét analysepanel.
panel <- list(V_Dem |> select(-ele_dem, -regime),
Manifesto_panel |> select(lande, år, prog_pol = prog_pol_locf),
WID, WB) |>
reduce(left_join, by = c("lande", "år"),
.init = expand_grid(lande = lande, år = .env$år))
dubletter_panel <- panel |> count(lande, år) |> filter(n > 1)
cat(nrow(panel), "rækker,", ncol(panel), "kolonner",
ifelse(nrow(dubletter_panel) == 0, "og ingen dubletter", "MEN DUBLETTER!"))
1015 rækker, 11 kolonner og ingen dubletter
Vi måler nu sammenhængen mellem de to polariseringsmål.
pol_within <- panel |>
group_by(lande) |>
mutate(samf_within = samf_pol - mean(samf_pol, na.rm = TRUE),
prog_within = prog_pol - mean(prog_pol, na.rm = TRUE)) |>
ungroup()
cat("Rå korrelation: r =",
round(cor(panel$samf_pol, panel$prog_pol,
use = "complete.obs"), 2), "\n")
Rå korrelation: r = -0.04
cat("Within-korrelation: r =",
round(cor(pol_within$samf_within, pol_within$prog_within,
use = "complete.obs"), 2))
Within-korrelation: r = 0.2
Den rå korrelation mellem de to mål er -0,04, og within-korrelationen er 0,20. Dette bekræfter, at samfundsmæssig og programmatisk polarisering er to forskellige fænomener.
saveRDS(panel, "Data/analysepanel.rds")
kontrol_panel <- readRDS("Data/analysepanel.rds")
if (identical(panel, kontrol_panel)) {
cat(paste0("Panelet er frosset: Data/analysepanel.rds (",
nrow(panel), " rækker og ", ncol(panel), " kolonner)"))
} else {
cat("FEJL: Det gemte panel afviger fra panelet i hukommelsen")
}
Panelet er frosset: Data/analysepanel.rds (1015 rækker og 11 kolonner)