...

Übungsprojekt: Saubere Daten

Diese Übung soll Dir helfen, den Umgang mit mehreren, ungleich benannten Datensätzen zu üben, sie zusammenzuführen, zu bereinigen und anschließend weiterzuverarbeiten – sowohl in R als auch in SPSS. Viel Erfolg und Spaß beim Umsetzen!

Aufgabenstellung

Du erhältst zwei CSV-Dateien:

  1. „uebung_dirty1.csv“ mit folgenden Variablen:
    • ID: Eindeutige Kennung der Person
    • geschl: Geschlecht (Kodierung: 1, 2, 1.0 und 9; 9 steht für unklare Angaben)
    • alter: Alter in Jahren (enthält fehlerhafte Werte wie 0 oder 999)
    • einkommen: Monatsnettoeinkommen in Euro (Fehlerwerte: -99, 99999)
    • Q1, Q2, Q3, Q4: Items eines Fragebogens (Skala 1–5; Q3 soll reverse coded werden)
  2. „uebung_dirty2.csv“ mit folgenden Variablen:
    • PersonID: Eindeutige Kennung der Person (entspricht ID in Datensatz 1)
    • sex: Geschlecht (Kodierung: „M“, „F“, „M.0“ und „unknown“)
    • age: Alter in Jahren (ähnliche Fehlerwerte wie in Datensatz 1)
    • income: Monatsnettoeinkommen in Euro (mit gleichen Fehlerwerten wie in Datensatz 1)
    • Item1, Item2, Item3, Item4: Fragebogenitems (Skala 1–5; Item3 soll reverse coded werden)

Hier sind die konkreten Datentabellen. Füge sie in einem ersten Schritt in eine eigene Datei ein – je nachdem, wie du die Übung selbst gestalten willst, kann das in eine .csv/.txt Datei oder z.B. direkt .sav sein.

Datensatz 1 – uebung_dirty1.csv

ID geschl alter einkommen Q1 Q2 Q3 Q4
1 1 22 2000 4 5 NA 3
2 9 17 0 3 2 1 4
3 2 19 1500 4 4 2 2
4 2 999 2500 5 NA 3 NA
5 2 19 -99 2 2 5 4
6 1 55 4000 4 4 4 4

Datensatz 2 – uebung_dirty2.csv

PersonID sex age income Item1 Item2 Item3 Item4
1 M 22 2000 4 5 NA 3
2 unknown 17 0 3 2 1 4
3 F 19 1500 4 4 2 2
6 M.0 55 4000 4 4 4 4
7 M 55 4000 4 4 4 4
8 F 30 3000 3 3 3 2

Wichtige Hinweise:

  • Die beiden Datensätze beziehen sich auf dieselben Personen, haben jedoch unterschiedliche Variablennamen (z. B. ID vs. PersonID, geschl vs. sex, alter vs. age, einkommen vs. income, Q1–Q4 vs. Item1–Item4).
  • Es müssen zunächst beide Datensätze so angepasst werden, dass die Variablennamen übereinstimmen (z. B. Umbenennen von Variablen) und dann anhand der Personenkennung zusammengeführt werden.
  • Zusätzlich gelten folgende Aufgaben:
    • Entferne Duplikate (z. B. wenn in einem Datensatz mehrere Fälle mit derselben ID vorkommen).
    • Setze fehlerhafte Werte als fehlend (NA in R bzw. SYSMIS in SPSS).
    • Reverse Coding: Q3 (bzw. Item3) soll umkodiert werden (bei einer Skala von 1 bis 5 = 6 – ursprünglicher Wert).
    • Entferne Fälle, bei denen alle vier Items (Q1, Q2, Q3, Q4 bzw. Item1, Item2, Item3, Item4) den Maximalwert (5) aufweisen.
    • Wandle die Geschlechtsvariable in einen Faktor um (in R: factor, in SPSS: Value Labels) – dabei sollen unterschiedliche Kodierungen (1, 1.0, „M“, „M.0“ etc.) einheitlich als „Maennlich“ bzw. „Weiblich“ interpretiert werden.
    • Erstelle eine neue Variable „alter_gruppe“ (z. B. <20 = „Jugend“, 20–64 = „Erwachsen“, ≥65 = „Senior“).
    • Berechne den Mittelwert der Items (Q1–Q4 bzw. Item1–Item4; nach Reverse Coding bei Q3/Item3) in einer neuen Variable Q_gesamt – allerdings nur, wenn mindestens zwei der vier Items vorliegen; andernfalls soll der Wert NA sein.
  1. Exportiere den bereinigten und zusammengeführten Datensatz als neue CSV-Datei (z. B. „uebung_clean.csv“) und zusätzlich in einem formatbezogenen Format (RDS in R, SAV in SPSS).
  2. Erstelle ein kurzes Protokoll, in dem Du dokumentierst, welche Schritte Du unternommen hast (z. B. Umbenennen von Variablen, Definition von fehlenden Werten, Reverse Coding, Zusammenführung etc.).

Musterlösung in R

library(dplyr)

### 1. Datensätze einlesen
# Datensatz 1
df1 <- read.csv2("uebung_dirty1.csv", header = TRUE, na.strings = c("NA", ""))
# Datensatz 2
df2 <- read.csv2("uebung_dirty2.csv", header = TRUE, na.strings = c("NA", ""))

### 2. Variablennamen angleichen
# Für df2: PersonID -> ID, sex -> geschl, age -> alter, income -> einkommen,
# Item1 -> Q1, Item2 -> Q2, Item3 -> Q3, Item4 -> Q4.
df2 <- df2 %>%
  rename(ID = PersonID,
         geschl = sex,
         alter = age,
         einkommen = income,
         Q1 = Item1,
         Q2 = Item2,
         Q3 = Item3,
         Q4 = Item4)

### 3. Daten zusammenführen (Merge)
# Angenommen, beide Datensätze haben dieselben Personen. Wir führen per Full Join anhand der ID zusammen.
df <- full_join(df1, df2, by = "ID", suffix = c("_1", "_2"))

# Nun müssen wir für jede Variable die Daten vereinheitlichen.
# Beispiel: für "geschl": Wir haben ggf. zwei Spalten: geschl_1 und geschl_2.
# Wir nehmen zunächst geschl_1, falls vorhanden, sonst geschl_2.
df <- df %>%
  mutate(geschl = ifelse(!is.na(geschl_1), as.character(geschl_1), as.character(geschl_2)),
         alter = ifelse(!is.na(alter_1), alter_1, alter_2),
         einkommen = ifelse(!is.na(einkommen_1), einkommen_1, einkommen_2),
         Q1 = ifelse(!is.na(Q1_1), Q1_1, Q1_2),
         Q2 = ifelse(!is.na(Q2_1), Q2_1, Q2_2),
         Q3 = ifelse(!is.na(Q3_1), Q3_1, Q3_2),
         Q4 = ifelse(!is.na(Q4_1), Q4_1, Q4_2)
  )

# Lösche die Hilfsspalten:
df <- df %>% select(ID, geschl, alter, einkommen, Q1, Q2, Q3, Q4)

### 4. Duplikate entfernen (auf Basis von ID)
df <- df[!duplicated(df$ID), ]

### 5. Fehlerhafte Werte bereinigen
# Geschlecht: Bei df können z.B. "9", "unknown" oder "M.0" vorkommen.
# Standardisiere: Werte, die "1", "1.0", "M", "M.0" enthalten => "Maennlich", "2", "F", "F.0", "F", "female" etc. => "Weiblich"
df$geschl <- toupper(df$geschl)  # in Großbuchstaben, um Vergleiche zu erleichtern
df$geschl[df$geschl %in% c("9", "UNKNOWN")] <- NA
df$geschl[df$geschl %in% c("1", "1.0", "M", "M.0")] <- "Maennlich"
df$geschl[df$geschl %in% c("2", "F", "F.0", "W")] <- "Weiblich"
df$geschl <- factor(df$geschl, levels = c("Maennlich", "Weiblich"))

# Alter: Werte <10 oder >100 als NA setzen
df$alter[df$alter < 10 | df$alter > 100] <- NA

# Einkommen: -99 oder >50000 als NA setzen
df$einkommen[df$einkommen == -99 | df$einkommen > 50000] <- NA

### 6. Reverse Coding von Q3
# Bei einer Skala von 1 bis 5: Neuer Wert = 6 - Originalwert
df$Q3 <- 6 - df$Q3

### 7. Entferne Fälle, bei denen alle Items (Q1–Q4) den Maximalwert 5 haben.
df <- df %>% filter(!(Q1 == 5 & Q2 == 5 & Q3 == 5 & Q4 == 5))

### 8. Neue Variablen erstellen
# Altersgruppen (z. B.: <20 = "Jugend", 20–64 = "Erwachsen", ≥65 = "Senior")
df <- df %>%
  mutate(alter_gruppe = case_when(
    !is.na(alter) & alter < 20 ~ "Jugend",
    !is.na(alter) & alter < 65 ~ "Erwachsen",
    !is.na(alter) & alter >= 65 ~ "Senior",
    TRUE ~ NA_character_
  ))

# Skalenmittelwert Q_gesamt berechnen (nur wenn mindestens 2 Items vorhanden sind)
df <- df %>%
  rowwise() %>%
  mutate(Q_gesamt = if_else(sum(!is.na(c_across(Q1:Q4))) >= 2,
                             mean(c_across(Q1:Q4), na.rm = TRUE),
                             NA_real_)) %>%
  ungroup()

### 9. Ergebnis prüfen
summary(df)
str(df)

### 10. Exportiere den bereinigten Datensatz
write.csv2(df, "uebung_clean.csv", row.names = FALSE)
saveRDS(df, file = "uebung_clean.rds")

Musterlösung in SPSS

Die SPSS-Syntax erfolgt in mehreren Schritten. Du kannst hierfür den SPSS-Dialog (über Menüführung) nutzen und die generierte Syntax anpassen.

Schritt 1: Import der beiden Datensätze

Datensatz 1 (uebung_dirty1.csv):

GET DATA
/TYPE=TXT
/FILE="C:\pfad\uebung_dirty1.csv"
/DELCASE=LINE
/DELIMITERS=";"
/QUALIFIER='"'
/ARRANGEMENT=DELIMITED
/FIRSTCASE=2
/VARIABLES=
ID F4.0
geschl F3.0
alter F4.0
einkommen F8.0
Q1 F2.0
Q2 F2.0
Q3 F2.0
Q4 F2.0
.
EXECUTE.
SAVE OUTFILE="C:\pfad\temp1.sav" /COMPRESSED.
EXECUTE.

Datensatz 2 (uebung_dirty2.csv):

plaintextKopierenGET DATA
  /TYPE=TXT
  /FILE="C:\pfad\uebung_dirty2.csv"
  /DELCASE=LINE
  /DELIMITERS=";"
  /QUALIFIER='"'
  /ARRANGEMENT=DELIMITED
  /FIRSTCASE=2
  /VARIABLES=
    PersonID F4.0
    sex A8
    age F4.0
    income F8.0
    Item1 F2.0
    Item2 F2.0
    Item3 F2.0
    Item4 F2.0
  .
EXECUTE.
SAVE OUTFILE="C:\pfad\temp2.sav" /COMPRESSED.
EXECUTE.

Schritt 2: Variablennamen angleichen in SPSS

Öffne beide Dateien nacheinander und benenne in Datensatz 2 die Variablen um. Dies kann über den Menüpunkt „Transform -> Rename Variables…“ erfolgen oder per Syntax:

plaintextKopieren* Öffne temp2.sav.
GET FILE="C:\pfad\temp2.sav".
RENAME VARIABLES (PersonID = ID) (sex = geschl) (age = alter) (income = einkommen)
                     (Item1 = Q1) (Item2 = Q2) (Item3 = Q3) (Item4 = Q4).
EXECUTE.
SAVE OUTFILE="C:\pfad\temp2_renamed.sav" /COMPRESSED.
EXECUTE.

Schritt 3: Zusammenführen der Datensätze

Melde Dich nun in SPSS zur Datei temp1.sav und führe einen Merge durch (über „Data -> Merge Files -> Add Cases…“):

plaintextKopierenGET FILE="C:\pfad\temp1.sav".
MATCH FILES
  /FILE=*
  /FILE="C:\pfad\temp2_renamed.sav"
  /BY ID.
EXECUTE.

Hinweis: Falls es Duplikate gibt, müssen diese später entfernt werden.

Schritt 4: Datenbereinigung

a) Duplikate entfernen (auf Basis der ID):

plaintextKopierenSORT CASES BY ID (A).
IF (LAG(ID)=ID) dup_flag = 1.
EXECUTE.
SELECT IF (dup_flag <> 1 OR MISSING(dup_flag)).
EXECUTE.

b) Fehlerhafte Werte als fehlend definieren:

plaintextKopieren* Geschlecht: Werte 9 oder "unknown" als fehlend setzen.
DO IF (geschl = 9 OR UPPER(STRING(geschl,F8.0)) = "UNKNOWN").
  COMPUTE geschl = SYSMIS(geschl).
END IF.
EXECUTE.

* Alter: Werte < 10 oder > 100 als fehlend.
DO IF (alter < 10 OR alter > 100).
  COMPUTE alter = SYSMIS(alter).
END IF.
EXECUTE.

* Einkommen: -99 oder >50000 als fehlend.
DO IF (einkommen = -99 OR einkommen > 50000).
  COMPUTE einkommen = SYSMIS(einkommen).
END IF.
EXECUTE.

c) Geschlecht als Faktor umkodieren:

Ergänze in der Variablenansicht (oder per Syntax):

plaintextKopierenVALUE LABELS geschl
  1 "Maennlich"
  2 "Weiblich".
EXECUTE.

Hinweis: Falls geschl als numerischer Wert vorliegt, stelle sicher, dass auch Werte wie 1.0 richtig interpretiert werden.

Schritt 5: Reverse Coding von Q3

plaintextKopierenCOMPUTE Q3_rev = 6 - Q3.
EXECUTE.
COMPUTE Q3 = Q3_rev.
EXECUTE.

Schritt 6: Entfernen fehlerhafter Fälle (alle Items = 5)

plaintextKopierenDO IF (Q1 = 5 AND Q2 = 5 AND Q3 = 5 AND Q4 = 5).
  COMPUTE flag_max = 1.
ELSE.
  COMPUTE flag_max = 0.
END IF.
EXECUTE.
SELECT IF (flag_max = 0).
EXECUTE.

Schritt 7: Neue Variable „alter_gruppe“ erstellen

plaintextKopierenRECODE alter (LO THRU 19 = 1) (20 THRU 64 = 2) (65 THRU HI = 3) INTO alter_gruppe.
EXECUTE.
VALUE LABELS alter_gruppe
  1 "Jugend"
  2 "Erwachsen"
  3 "Senior".
EXECUTE.

Schritt 8: Skalenmittelwert Q_gesamt berechnen

plaintextKopieren* Summe der Items.
COMPUTE sumQ = Q1 + Q2 + Q3 + Q4.
EXECUTE.
* Anzahl der nicht fehlenden Items.
COMPUTE countQ = (NOT MISSING(Q1)) + (NOT MISSING(Q2)) + (NOT MISSING(Q3)) + (NOT MISSING(Q4)).
EXECUTE.
* Mittelwert nur berechnen, wenn countQ >= 2.
IF (countQ >= 2) Q_gesamt = sumQ / countQ.
EXECUTE.

Schritt 9: Export des bereinigten Datensatzes

Als CSV:

plaintextKopierenSAVE TRANSLATE
  /OUTFILE="C:\pfad\uebung_clean.csv"
  /TYPE=CSV
  /MAP
  /FIELDNAMES
  /REPLACE.
EXECUTE.

Oder als SPSS-Datei (SAV):

plaintextKopierenSAVE OUTFILE="C:\pfad\uebung_clean.sav"
/COMPRESSED.
EXECUTE.

Alles klar?

Ich hoffe, der Beitrag war für dich soweit verständlich. Wenn du weitere Fragen hast, nutze bitte hier die Möglichkeit, eine Frage an mich zu stellen!