4 Datenimport und Inspektion
Wer trägt islamfeindliche Einstellungen in Deutschland 2023?
Bevor du diese Frage beantworten kannst, brauchst du den Datensatz auf deinem Rechner — und du musst ihn so weit verstehen, dass du gezielt die richtigen Variablen herausziehen kannst. Dieses Kapitel begleitet dich vom Einlesen der SPSS-Datei über die ersten Inspektionsschritte bis zur sauberen Behandlung fehlender Werte. In Kapitel 5 baust du dann auf diesem Fundament die zwei Skalen der Mini-Studie auf.
Forschungsjournal: Wo stehst du in deiner Mini-Studie? Werkzeug steht (Kap. 1–3). Jetzt beginnt die eigentliche Forschungsarbeit. Mit diesem Kapitel hältst du am Ende einen Analyse-Datensatz in der Hand: 5.246 Befragte, dein eigenes Variablenset, fehlende Werte deklariert. Das ist der Rohzustand, von dem aus alle weiteren Etappen aufbauen.
4.1 Worum es geht
Stell dir vor, du bekommst von einer Kollegin einen USB-Stick mit der Aufschrift „ALLBUS 2023 — viel Spaß”. Du steckst ihn ein und öffnest die Datei. Was du siehst, ist nicht das, was du dir erhofft hast: 579 Spalten mit Namen wie mm01, pa29, pt06, wghtpew. Vier verschiedene negative Zahlen tauchen als „Wert” auf — -9, -11, -42. Manche Variablen sind als Zahl gespeichert, obwohl sie eigentlich eine Kategorie sind (sex = 1 heißt „Mann”). Und die wirklichen Beschriftungen — das, was tatsächlich gefragt wurde — liegen irgendwo versteckt, unsichtbar im Hintergrund.
Genau dieser Zustand ist normal. Sekundärdatensätze aus der quantitativen Sozialforschung sehen immer so aus. Sie sind so gebaut, dass viele Menschen sie für viele unterschiedliche Fragen nutzen können — und das geht nur, wenn die Daten zunächst roh bleiben. Deine Aufgabe ist es, aus diesem Rohzustand einen Analyse-Datensatz zu machen, der zu deiner Forschungsfrage passt.
Diese Schritte sind keine Vorarbeit, die man möglichst schnell hinter sich bringt. Sie sind der methodische Kern jeder ehrlichen Auswertung: Welche Fälle nimmst du raus? Wie behandelst du fehlende Werte? Wie übersetzt du mm01 = 7 in „diese Person lehnt Muslime stark ab”? Jede dieser Entscheidungen beeinflusst, was am Ende rauskommt — und jede gehört in eine Pipeline, die du jederzeit reproduzieren kannst. Das ist offene Wissenschaft im konkreten Handwerk.
Dieses Kapitel ist der Anker für alles, was folgt. Du legst hier den Analyse-Datensatz an, mit dem du in Kapitel 7 Verteilungen beschreibst, in Kapitel 8 Strukturen prüfst und in Kapitel 9 Hypothesen modellierst. Wenn dieser Anker hält, halten alle späteren Befunde.
Was du nach diesem Kapitel kannst
- Einen SPSS-Datensatz mit
read_spss()einlesen — inklusive aller Variablen- und Wertelabels. - Variablen über Name oder Label mit
find_var()suchen. - Detail-Codebooks für ausgewählte Variablen mit
codebook()erzeugen. - Variablen und Fälle gezielt auswählen, filtern, sortieren und umsortieren (
select(),filter(),arrange(),relocate()). - Den
<haven_labelled>-Datentyp verstehen und ihn bei Bedarf in Faktor oder numerisch konvertieren. - Variablenlabels und Wertelabels lesen, auslesen und setzen.
- Fehlende Werte deklarieren und mit
na_frequencies(),set_na()unddrop_na()systematisch behandeln.
4.2 Setup
In jeder R-Sitzung lädst du zuerst die Pakete, mit denen du arbeitest. In diesem Buch sind das durchgehend nur zwei:
SPSS → R. In SPSS bist du gewohnt, dass alle Funktionen direkt verfügbar sind. In R aktivierst du dir mit library() gezielt die Werkzeuge, die du brauchst — das hält den Funktions-Namensraum übersichtlich und macht jeden Schritt nachvollziehbar.
4.3 Datensatz einlesen
Der ALLBUS 2023 liegt als SPSS-Datei (ALLBUS2023.sav) im Projektordner. Mit read_spss() aus mariposa liest du sie ein:
allbus <- read_spss("ALLBUS2023.sav")allbus ist jetzt ein Tibble — ein moderner Datentyp im tidyverse. Tibbles verhalten sich wie klassische Data Frames, drucken aber kompakter und behalten ihre Spaltentypen besser. Was wir geladen haben:
allbus# A tibble: 5,246 × 579
za_nr doi version respid substudy mode splt23_1 splt23_2
<dbl+lbl> <chr> <chr> <dbl> <dbl+lbl> <dbl+l> <dbl+lbl> <dbl+lbl>
1 8831 [ALLBUSc… http… v1.3.0… 1 NA(a) [TNZ… 2 [CAP… NA(a) [TNZ… 2 [SPL…
2 8831 [ALLBUSc… http… v1.3.0… 2 1 [SIM… 3 [CAW… 1 [SPL… -15 [TNZ…
3 8831 [ALLBUSc… http… v1.3.0… 3 1 [SIM… 4 [MAI… 1 [SPL… -15 [TNZ…
4 8831 [ALLBUSc… http… v1.3.0… 4 1 [SIM… 4 [MAI… 1 [SPL… -15 [TNZ…
5 8831 [ALLBUSc… http… v1.3.0… 5 2 [SEQ… 3 [CAW… 2 [SPL… -15 [TNZ…
6 8831 [ALLBUSc… http… v1.3.0… 6 NA(a) [TNZ… 2 [CAP… NA(a) [TNZ… 1 [SPL…
7 8831 [ALLBUSc… http… v1.3.0… 7 1 [SIM… 4 [MAI… 1 [SPL… -15 [TNZ…
8 8831 [ALLBUSc… http… v1.3.0… 8 1 [SIM… 3 [CAW… 1 [SPL… -15 [TNZ…
9 8831 [ALLBUSc… http… v1.3.0… 9 2 [SEQ… 3 [CAW… 2 [SPL… -15 [TNZ…
10 8831 [ALLBUSc… http… v1.3.0… 10 NA(a) [TNZ… 2 [CAP… NA(a) [TNZ… 2 [SPL…
# ℹ 5,236 more rows
# ℹ 571 more variables: eastwest <dbl+lbl>, german <dbl+lbl>, ep01 <dbl+lbl>,
# ep03 <dbl+lbl>, ep04 <dbl+lbl>, ep06 <dbl+lbl>, xr19 <dbl+lbl>,
# xr20 <dbl+lbl>, lm27 <dbl+lbl>, lm28 <dbl+lbl>, lm29 <dbl+lbl>,
# lm30 <dbl+lbl>, lm31 <dbl+lbl>, lm32 <dbl+lbl>, lm33 <dbl+lbl>,
# lm34 <dbl+lbl>, la01 <dbl+lbl>, li01 <dbl+lbl>, li02 <dbl+lbl>,
# li03 <dbl+lbl>, li04 <dbl+lbl>, li05 <dbl+lbl>, li09 <dbl+lbl>, …
Im Kopf siehst du 5,246 × 579 — der Datensatz hat 5.246 Fälle und 579 Variablen. Darunter eine Auswahl der ersten Spalten mit ihren Datentypen.
Hintergrund: Was passiert beim Einlesen? read_spss() aus mariposa verwendet im Hintergrund das Paket haven und reichert die Daten mit zwei Eigenschaften an, die du aus SPSS kennst: Variablenlabels (eine ausführliche Beschriftung pro Spalte) und Wertelabels (eine Beschriftung pro Ausprägung). Beide Informationen bleiben unsichtbar in den Spalten gespeichert — du kannst sie jederzeit abrufen oder als Faktor sichtbar machen.
Falls du Daten in anderen Formaten brauchst, gibt es passende Geschwister-Funktionen:
read_stata("datei.dta") # Stata
read_sas("datei.sas7bdat") # SAS
read_xlsx("datei.xlsx") # ExcelUnd wenn du einen bearbeiteten Datensatz zurück nach SPSS exportieren möchtest:
write_spss(allbus, "allbus_bearbeitet.sav")4.4 Erster Blick auf den Datensatz
Bei knapp 600 Variablen ist es unmöglich, sich alles in der Konsole anzeigen zu lassen. Drei Werkzeuge helfen dir bei der Orientierung:
4.4.1 Variablen finden mit find_var()
Die Variablennamen im ALLBUS sind kryptisch (mm01, pa29, wghtpew). Was wirklich gemessen wird, steht im Variablenlabel. mariposas find_var() durchsucht beide gleichzeitig — Name und Label — und liefert dir die Treffer als kleine Übersichtstabelle:
allbus |> find_var("muslim") col name label
1 194 mm03 ANWESENHEIT VON MUSLIMEN BRINGT KONFLIKT
2 196 mm05 MUSLIMISCHER BUERGERMEISTER IN ORDNUNG
3 197 mm06 UNTER MUSLIMEN SIND VIELE REL. FANATIKER
Damit findest du die sechs mm-Items für unsere Islamfeindlichkeits-Skala. Standardmäßig wird in Namen und Labels gesucht; mit search = "label" schränkst du auf Labels ein, mit search = "name" auf Namen:
allbus |> find_var("alter", search = "label") col name label
1 93 age ALTER: BEFRAGTE(R)
2 94 agec ALTER: BEFRAGTE(R), KATEGORISIERT
3 265 is01 PERSOENLICH.ALTERSSICHERUNG AUSREICHEND?
4 311 dw12a BEFR.: ALTER BEI AUFGABE DES BERUFS
5 333 scage GEGENWAERTIGER EHEPARTNER: ALTER
6 334 scagec GEGENWAERTIGER EHEPARTNER: ALTER, KAT.
7 367 page LEBENSPARTNER: ALTER
8 368 pagec LEBENSPARTNER: ALTER, KAT.
9 434 hh2age 2.HAUSH.PERSON: ALTER
10 439 hh3age 3.HAUSH.PERSON: ALTER
11 444 hh4age 4.HAUSH.PERSON: ALTER
12 449 hh5age 5.HAUSH.PERSON: ALTER
13 454 hh6age 6.HAUSH.PERSON: ALTER
14 459 hh7age 7.HAUSH.PERSON: ALTER
15 464 hh8age 8.HAUSH.PERSON: ALTER
16 471 dh17 ALTER JUENGSTES HAUSHALTSMITGLIED
17 480 kh1age ALTER, 1.KIND, AUSSER HAUS
18 483 kh2age ALTER, 2.KIND, AUSSER HAUS
19 486 kh3age ALTER, 3.KIND, AUSSER HAUS
20 489 kh4age ALTER, 4.KIND, AUSSER HAUS
21 492 kh5age ALTER, 5.KIND, AUSSER HAUS
22 495 kh6age ALTER, 6.KIND, AUSSER HAUS
23 498 kh7age ALTER, 7.KIND, AUSSER HAUS
24 501 kh8age ALTER, 8.KIND, AUSSER HAUS
25 504 kh9age ALTER, 9.KIND, AUSSER HAUS
26 507 kh10age ALTER, 10.KIND, AUSSER HAUS
27 573 xi03 INTERVIEWER(IN): ALTER
allbus |> find_var("^mm", search = "name") # regex: alle mm-Items col name label
1 170 mm07 FUER DEN BAU VON MOSCHEEN IN BRD?
2 192 mm01 ISLAMAUSUEBUNG IN DEUTSCHL. BESCHRAENKEN
3 193 mm02 ISLAM PASST IN DIE DEUTSCHE GESELLSCHAFT
4 194 mm03 ANWESENHEIT VON MUSLIMEN BRINGT KONFLIKT
5 195 mm04 STAAT SOLLTE ISLAM. GRUPPEN BEOBACHTEN
6 196 mm05 MUSLIMISCHER BUERGERMEISTER IN ORDNUNG
7 197 mm06 UNTER MUSLIMEN SIND VIELE REL. FANATIKER
SPSS → R. In SPSS kennst du DISPLAY DICTIONARY für eine Gesamtübersicht. find_var() ist gezielter: du suchst nach einem inhaltlichen Stichwort und bekommst sofort die passenden Variablen — selbst wenn du die kryptischen Namen nicht im Kopf hast.
4.4.2 Detail-Übersicht mit codebook()
Für eine bestimmte Auswahl von Variablen liefert codebook() aus mariposa eine schöne HTML-Übersicht mit Labels, Ausprägungen und Häufigkeiten. Das ist das R-Äquivalent zum SPSS-DISPLAY DICTIONARY:
allbus |>
codebook(mm01, mm02, mm03, mm04, mm05, mm06)SPSS → R: Dateninspektion. | SPSS | R | | ——————————- | ——————————– | | FREQUENCIES VARIABLES=mm01. | allbus \|> frequency(mm01) | | DESCRIPTIVES VARIABLES=age. | allbus \|> describe(age) | | DISPLAY DICTIONARY. | allbus \|> codebook(...) |
Reviewer-Hinweis. In einer Methodenbeschreibung gehört zu jeder Skala ein Mini-Codebook: Wortlaut der Items, Antwortformat, Missing-Behandlung, N pro Item. Wer das in codebook() als Tabelle generiert und in den Anhang seines Berichts schreibt, hat den Forschungsstandard erfüllt.
4.5 Variablen und Fälle auswählen
Die dplyr-Funktionen select(), filter() und arrange() sind dein tägliches Werkzeug, um aus einem großen Datensatz das herauszuholen, was du gerade brauchst.
4.5.1 Variablen auswählen mit select()
allbus |>
select(mm01, mm02, mm03)# A tibble: 5,246 × 3
mm01 mm02 mm03
<dbl+lbl> <dbl+lbl> <dbl+lbl>
1 5 [..] 3 [..] 4 [..]
2 NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT]
3 NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT]
4 NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT]
5 2 [..] 4 [..] 4 [..]
6 3 [..] 3 [..] 3 [..]
7 NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT]
8 NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT] NA(b) [TNZ: SPLIT]
9 1 [STIMME GAR NICHT ZU] 6 [..] 2 [..]
10 7 [STIMME VOLL+GANZ ZU] 1 [STIMME GAR NICHT ZU] 3 [..]
# ℹ 5,236 more rows
Du kannst Bereiche mit : angeben und Variablen mit - ausschließen:
allbus |>
select(mm01:mm06, eastwest, sex, age, educ)# A tibble: 5,246 × 10
mm01 mm02 mm03 mm04 mm05 mm06
<dbl+lbl> <dbl+lbl> <dbl+lbl> <dbl+lbl> <dbl+lbl> <dbl+lbl>
1 5 [..] 3 [..] 4 [..] 2 [..] 6 [..] 2 [..]
2 NA(b) [TNZ: SPLI… NA(b) [TNZ… NA(b) [TNZ… NA(b) [TNZ… NA(a) [TNZ… NA(a) [TNZ…
3 NA(b) [TNZ: SPLI… NA(b) [TNZ… NA(b) [TNZ… NA(b) [TNZ… NA(a) [TNZ… NA(a) [TNZ…
4 NA(b) [TNZ: SPLI… NA(b) [TNZ… NA(b) [TNZ… NA(b) [TNZ… NA(a) [TNZ… NA(a) [TNZ…
5 2 [..] 4 [..] 4 [..] 3 [..] 3 [..] 6 [..]
6 3 [..] 3 [..] 3 [..] 7 [STI… 6 [..] 3 [..]
7 NA(b) [TNZ: SPLI… NA(b) [TNZ… NA(b) [TNZ… NA(b) [TNZ… NA(a) [TNZ… NA(a) [TNZ…
8 NA(b) [TNZ: SPLI… NA(b) [TNZ… NA(b) [TNZ… NA(b) [TNZ… NA(a) [TNZ… NA(a) [TNZ…
9 1 [STIMME GA… 6 [..] 2 [..] 1 [STI… 7 [STI… 2 [..]
10 7 [STIMME VO… 1 [STI… 3 [..] 6 [..] 1 [STI… 7 [STI…
# ℹ 5,236 more rows
# ℹ 4 more variables: eastwest <dbl+lbl>, sex <dbl+lbl>, age <dbl+lbl>,
# educ <dbl+lbl>
Diese Auswahl — die sechs Skalen-Items plus Demografie — ist genau das, was du für die Mini-Studie brauchst.
Zwei nahe Verwandte von select():
-
pull(var)zieht eine einzelne Spalte als reinen Vektor heraus — nützlich, wenn du den Spalteninhalt direkt in eine Funktion füttern willst, die kein Tibble erwartet:allbus |> pull(age) |> mean(na.rm = TRUE). -
relocate(var, .before = X, .after = Y)sortiert Spalten um, ohne welche zu entfernen — praktisch, wenn die wichtigsten Variablen vorne stehen sollen:allbus |> relocate(islamophobie, populismus, .before = sex).
4.5.2 Fälle filtern mit filter()
# A tibble: 2,672 × 3
sex age educ
<dbl+lbl> <dbl+lbl> <dbl+lbl>
1 2 [FRAU] 69 4 [FACHHOCHSCHULREIFE]
2 2 [FRAU] 18 5 [HOCHSCHULREIFE]
3 2 [FRAU] 45 5 [HOCHSCHULREIFE]
4 2 [FRAU] 26 3 [MITTLERE REIFE]
5 2 [FRAU] 71 2 [VOLKS-,HAUPTSCHULE]
6 2 [FRAU] 66 2 [VOLKS-,HAUPTSCHULE]
7 2 [FRAU] 39 3 [MITTLERE REIFE]
8 2 [FRAU] 51 3 [MITTLERE REIFE]
9 2 [FRAU] 29 5 [HOCHSCHULREIFE]
10 2 [FRAU] 60 4 [FACHHOCHSCHULREIFE]
# ℹ 2,662 more rows
Die Vergleichs- und Logik-Operatoren aus Kapitel 3.4 (==, !=, <, >, &, |, %in%) bilden hier dein Vokabular. Komplexere Filter kombinierst du frei:
[1] 825
Vorsicht: Fehlende Werte. filter() schließt Fälle mit NA in der Bedingung automatisch aus. Das ist meist gewünscht, kann dich aber überraschen. Mit filter(is.na(variable)) filterst du gezielt fehlende Werte heraus.
4.5.3 Fälle sortieren mit arrange()
# A tibble: 5 × 2
age educ
<dbl+lbl> <dbl+lbl>
1 18 5 [HOCHSCHULREIFE]
2 18 5 [HOCHSCHULREIFE]
3 18 3 [MITTLERE REIFE]
4 18 1 [OHNE ABSCHLUSS]
5 18 2 [VOLKS-,HAUPTSCHULE]
Absteigend mit desc():
4.6 Datentypen verstehen
Wenn du in SPSS arbeitest, fragst du dich selten, welcher Typ eine Variable ist. SPSS macht das im Hintergrund: eine Variable ist „numerisch” oder „string”, und Wertelabels („1 = Mann, 2 = Frau”) sind nur eine Beschriftungs-Schicht obendrauf. In R ist das ein bisschen anders — und am Anfang verwirrend.
R kennt eine ganze Reihe von Datentypen: reine Zahlen (numeric), Text (character), Logik (logical), Kategorien mit fester Reihenfolge (factor). Beim Einlesen eines SPSS-Datensatzes kommt noch ein vierter Typ hinzu, den mariposa von haven übernimmt: <haven_labelled>. Das ist eine Art Hybrid: Die Spalte verhält sich nach außen wie eine Zahl, aber im Hintergrund tragen die Werte ihre SPSS-Wertelabels mit. So bleibt die Information „1 bedeutet Mann” erhalten, ohne dass du sie aus dem Codebook nachschlagen musst.
Mit class() siehst du den Typ einer Variable:
class(allbus$sex)[1] "haven_labelled" "vctrs_vctr" "double"
class(allbus$age)[1] "haven_labelled" "vctrs_vctr" "double"
Drei Konvertierungen wirst du immer wieder brauchen:
| Funktion | Wirkung |
|---|---|
to_label(data, var) |
wandelt <haven_labelled> in einen Faktor mit den Wertelabels als Stufen — Standard, wenn du in ggplot()-Achsen lesbare Beschriftungen willst |
to_numeric(data, var) |
wandelt in einen reinen numerischen Vektor — Labels gehen verloren |
to_labelled(data, var, labels = ...) |
wandelt umgekehrt einen Faktor zurück in ein <haven_labelled>
|
# A tibble: 3 × 2
sex eastwest
<fct> <fct>
1 MANN ALTE BUNDESLAENDER
2 MANN ALTE BUNDESLAENDER
3 FRAU ALTE BUNDESLAENDER
Wenn du nur Labels abstreifen willst (z. B. weil eine Funktion mit labelled-Vektoren nicht klarkommt), nimmst du unlabel(): allbus |> unlabel(sex, age). Selten gebraucht, aber gut zu wissen, wenn ein fremdes Paket sich quer stellt.
Hintergrund: Warum nicht einfach Faktor? In SPSS sind Variablen entweder numerisch oder string. Wertelabels sind ein Zusatz. In R gibt es Faktoren (Kategorien) und numerische Vektoren als getrennte Typen. <haven_labelled> ist eine Brücke: Du arbeitest mit Zahlen, aber die Wertelabels reisen mit. Wann du das auflösen solltest:
-
to_label()wenn du sortierst, gruppierst, kreuztabellierst oder plottest — Faktoren liefern lesbare Outputs. -
to_numeric()wenn du rechnest oder skalierst — z. B. bei Likert-Items, die du als pseudo-metrisch behandelst. - Beim Original lassen, wenn die Variable noch nicht final ist und du das Label später noch brauchst.
4.7 Variablen- und Wertelabels lesen und setzen
| Funktion | Wirkung |
|---|---|
var_label(data) |
Variablenlabels auslesen |
var_label(data) <- list(var = "Neue Beschriftung") |
Variablenlabel setzen |
val_labels(data) |
Wertelabels auslesen |
drop_labels(data) |
Alle Wertelabels entfernen, deren Ausprägung in den Daten gar nicht vorkommt |
mm01
"ISLAMAUSUEBUNG IN DEUTSCHL. BESCHRAENKEN"
mm02
"ISLAM PASST IN DIE DEUTSCHE GESELLSCHAFT"
mm03
"ANWESENHEIT VON MUSLIMEN BRINGT KONFLIKT"
Das Ergebnis ist ein benannter Character-Vektor — pro Variable das hinterlegte Label. So liest du, was eine kryptische Variable wie mm01 eigentlich bedeutet, ohne ins Codebook zu schauen.
4.8 Fehlende Werte deklarieren
Fehlende Werte sind in der Sozialforschung Normalität, nicht Ausnahme. Niemand beantwortet jede Frage einer Umfrage — manche überspringen einzelne Punkte, manche wissen es schlicht nicht, manche bekommen wegen eines Split-Designs bestimmte Fragen gar nicht vorgelegt. Und manche Antworten waren ursprünglich da, gingen aber durch einen Datenfehler verloren.
Die GESIS unterscheidet in ALLBUS deshalb vier Arten von fehlenden Werten und kodiert sie mit klar unterscheidbaren negativen Zahlen:
| Code | Bedeutung |
|---|---|
-42 |
DATENFEHLER |
-11 |
TNZ (trifft nicht zu / Split-Modul) |
-9 |
KEINE ANGABE |
-8 |
WEISS NICHT |
Die Unterscheidung ist inhaltlich wichtig: ein „weiß nicht” ist methodisch etwas anderes als eine verweigerte Antwort, und ein „trifft nicht zu” (jemand hat die Frage gar nicht gestellt bekommen) ist wiederum etwas anderes als ein echter Datenfehler. Wenn du diese Codes als reguläre Zahlen behandelst — was passiert, wenn du sie einfach in einen Mittelwert wirfst — sind deine Ergebnisse Müll: ein „Durchschnittswert” von -3.4 für Lebenszufriedenheit ist offensichtlich Unsinn.
Beim Einlesen werden diese in SPSS als user-missing deklarierten Codes automatisch zu tagged NAs. „Tagged” heißt: sie zählen in Berechnungen als NA (also fehlend), behalten aber im Hintergrund die Information, welcher Missing-Typ sie sind. Du kannst sie also später trotzdem voneinander unterscheiden — etwa um zu zeigen, wie viele Personen „weiß nicht” gewählt haben.
Hintergrund: Split-Designs im ALLBUS. Manche Itembatterien werden nur einer Hälfte der Stichprobe gestellt (Code -11 für die andere Hälfte). Das gilt insbesondere für die mm-Items unserer Islamfeindlichkeits-Skala. Die effektive N für solche Splits liegt deshalb bei rund 2.500 statt 5.246 — methodisch kein Fehler, sondern Stichprobenarchitektur. In der Methodenbeschreibung gehört dieser Punkt erwähnt.
Wie viele Fälle pro Missing-Code in einer konkreten Variable stecken, zeigt dir na_frequencies():
na_frequencies(allbus$mm01) tag n code label
1 b 1647 -11 TNZ: SPLIT
2 d 123 -8 WEISS NICHT
3 c 73 -9 KEINE ANGABE
4 a 2 -42 DATENFEHLER: MFN
5 <NA> 0 <NA> (System Missing)
Du siehst die Aufschlüsselung: wie viele „weiß nicht”, wie viele „keine Angabe”, wie viele „trifft nicht zu” — alles in einem Aufruf. Praktisch, bevor du entscheidest, ob du bestimmte Codes als reguläre Werte behältst oder als endgültige Missings behandelst.
Wenn du eine Variable hast, in der bestimmte Werte erst nachträglich als fehlend gelten sollen — etwa Altersangaben über 100 als unplausibel —, deklarierst du sie mit set_na():
Mit verbose = TRUE zeigt mariposa dir an, wie viele Fälle pro Wert zu NA wurden — kontrolliert und nachvollziehbar.
Mit drop_na() (aus tidyr) entfernst du Fälle mit NA:
Vorsicht: Listenweiser Ausschluss. drop_na() schließt Fälle aus, sobald eine der ausgewählten Variablen NA ist. Das ist klassischer listwise deletion. Wenn du in einer großen Pipeline mit vielen Variablen drop_na() rufst, kann deine Fallzahl drastisch schrumpfen. Setze drop_na() deshalb gezielt auf die Variablen, die du wirklich brauchst.
Hintergrund: MCAR, MAR, MNAR. Die Methodenliteratur unterscheidet drei Missing-Mechanismen: Missing Completely at Random (Zufall, keine Verzerrung), Missing at Random (Zufall bedingt durch beobachtete Variablen, durch Modellierung korrigierbar) und Missing Not at Random (systematisch, schwer zu beheben). In Survey-Daten wie ALLBUS ist MAR der Regelfall; einfache Listwise Deletion (drop_na()) ist dann ein konservativer, aber transparenter Umgang. Imputationsverfahren (z. B. mice) sind die nächste Ausbaustufe — für ein Einsteigerbuch jedoch zu viel.
Übungen
Du willst eine Skala zu Vertrauen in Institutionen bauen, kennst aber die Variablennamen nicht auswendig. Nutze find_var(), um (a) alle Variablen mit „vertrau” im Label und (b) alle Variablen mit st am Namensanfang zu finden.
Erstelle ein codebook() für die Items pt01 bis pt08 (Vertrauen in verschiedene Institutionen). Schau dir Labels und Wertelabels an.
allbus |>
codebook(pt01, pt02, pt03, pt04, pt05, pt06, pt07, pt08)Erstelle einen Datensatz analyse, der nur die für die Mini-Studie nötigen Variablen enthält (mm01:mm06, pa29:pa35, eastwest, sex, age, educ, wghtpew) und nur Fälle, in denen mindestens fünf der sechs mm-Items gültig sind. Tipp: rowSums(!is.na(across(mm01:mm06))) >= 5 als Filterkriterium.
Wähle ein Thema, das dich politik- oder sozialwissenschaftlich interessiert (Migration, Klima, Geschlechterrollen, …). Finde mit find_var() zwei bis drei Variablen im ALLBUS 2023, die deine Frage beleuchten könnten. Erstelle ein codebook() für deine Auswahl. Beschreibe in 2–3 Sätzen, was du untersuchen würdest und welche Variable als unabhängige bzw. abhängige Variable dienen könnte.
Es gibt hier keine Musterlösung — die Übung trainiert das Auffinden und Verstehen von Variablen, nicht eine bestimmte Antwort.
Forschungsjournal: Stand deiner Mini-Studie. Du hast den ALLBUS 2023 eingelesen und hast die Werkzeuge, um durch 579 Variablen gezielt zu navigieren. Du weißt, was hinter mm01 bis mm06 steckt (die sechs Islamfeindlichkeits-Items), du kennst die Missing-Codes der GESIS, und du kannst dein Analyse-Subset gezielt zusammenstellen. Was als Nächstes kommt: In Kapitel 5 wandelst du die Rohitems in zwei Skalen um — Islamfeindlichkeit und Populismus.
Was du jetzt weißt
- Du liest SPSS-Daten mit
read_spss()ein und behältst Variablen- und Wertelabels. - Du findest Variablen über Name oder Label mit
find_var()und holst dir Detail-Codebooks percodebook(). - Du wählst Variablen und Fälle mit
select(),filter(),arrange()aus — und sortierst sie mitrelocate()um. - Du verstehst den
<haven_labelled>-Typ und wandelst ihn bei Bedarf in Faktor oder numerisch. - Du liest und setzt Variablen- und Wertelabels mit
var_label()undval_labels(). - Du erkennst die ALLBUS-Missing-Codes, prüfst sie mit
na_frequencies()und schließt Fälle gezielt aus.
Im nächsten Kapitel (Kapitel 5) lernst du, wie du aus diesen Rohvariablen die zwei Skalen baust, die die Mini-Studie trägt — Islamfeindlichkeit und Populismus.
Weiterführend
- mariposa-Vignetten „Data I/O” und „Labels and Missing Values”.
- Hadley Wickham & Garrett Grolemund, R for Data Science (2e), Kapitel „Data Import” und „Data Transformation”.
- Joseph Larmarange, „labelled” Vignetten — vertiefte Auseinandersetzung mit labelled-Datentypen.
- GESIS, Datensatzbeschreibung ALLBUS 2023 (ZA8901) — Methodenbericht und Codeplan.