Übung

Datenvorbereitung
Letzte Änderung am 24. Februar 2021


Im Folgenden wollen wir einige Aufgaben bearbeiten, die in den Bereich der Datenvorbereitung fallen. Dazu gehören u.a. das Extrahieren und Sortieren von Daten, die Änderung der Kodierung von Daten sowie das Erstellen von Summary-Variablen. Zuallererst sollten wir uns jedoch immer mit dem genutzten Datensatz vertraut machen.

Dazu nutzen wir einen Datensatz, der im Rahmen eines Projektes zur Untersuchung des Zusammenhangs des Bedürfnisses nach Privatsphäre und verschiedenen Persönlichkeitseigenschaften erhoben wurde. Mehr Informationen zum Projekt und zur Publikation finden wir hier.

Den Datensatz sowie das dazugehörige Codebuch finden wir im Open Science Framework. Mehr Informationen zu OSF, der Replikationskrise und der Open Science Bewegung finden wir hier.

Den Datensatz können wir, nachdem wir ihn heruntergeladen haben, folgendermaßen in R einlesen:

data <- read.csv("Dateipfad/data.csv") # hier den eigenen Dateipfad einfügen

So sollte der Datensatz aussehen:


Übung 1: Erste Schritte

Zuallererst wollen wir uns mit dem Datensatz vertraut machen. Dazu benötigen wir das Codebuch, welches uns Informationen über die erhobenen Variablen sowie deren Messung gibt. Am besten überfliegen wir das Codebuch und den Datensatz einmal, um uns damit vertraut zu machen, bevor wir die nachfolgenden Aufgaben bearbeiten.

exclamation Es sind nicht alle Variablen, die im Codebuch auftauchen, auch im Datensatz.

1.) Es gibt zwei Variablen im Datensatz, die nicht im Codebuch zu finden sind. Welche sind das?

Lösung

Die Variable sex taucht nicht im Datensatz auf. Nur die Variable male, welche die Ausprägungen 0 und 1 besitzt. Schätzungsweise soll mit beiden dieselbe Information koderit werden: das biologische Geschlecht der befragten Personen.

Die Variable time taucht nicht im Codebuch auf. Möglicherweise ist das die individuelle Bearbeitungszeit für den Fragebogen in Sekunden. Vor der Nutzung der der Variablen time müssten wir deren Bedeutung klären.


2.) Wie viele Variablen und Beobachtungen enthält der Datensatz?

Tipp Standardmäßig sind Variablen die Spalten und Beobachtungen die Zeilen eines Datensatzes.

Lösung

Wir finden die Information im R Studio Feld Environment

… oder indem wir folgende Funktionen nutzen:

ncol(data) # Variablen = Anzahl der Spalten
[1] 70
nrow(data) # Beobachtungen (Personen; N) = Anzahl der Zeilen
[1] 296


3.) Liegen alle Variablen in einem ihrem Messniveau angemessenen Datentyp vor?

Tipp Im Codebuch finden wir Informationen zu den Variablen. Über die Funktionen str() bekommen wir Informationen zum Datentyp.

Lösung
str(data)
'data.frame':   296 obs. of  70 variables:
 $ id           : int  1 2 3 4 5 6 7 8 9 10 ...
 $ male         : int  0 1 0 0 0 0 1 1 0 0 ...
 $ age          : int  19 19 20 19 22 20 20 18 19 19 ...
 $ inc          : int  2 3 1 2 3 2 1 1 1 3 ...
 $ time         : int  2456 1414 828 1043 1806 1133 1625 2319 7129 1343 ...
 $ pri_nee_gen_1: int  6 7 5 6 4 5 6 5 4 4 ...
 $ pri_nee_gen_2: int  6 2 5 3 5 4 6 6 3 4 ...
 $ pri_nee_gen_3: int  6 6 4 6 7 6 5 7 4 6 ...
 $ pri_nee_gen_4: int  7 7 5 6 7 6 7 7 6 6 ...
 $ pri_nee_soc_1: int  2 4 5 2 5 4 5 4 1 6 ...
 $ pri_nee_soc_2: int  4 5 4 2 5 4 6 4 2 6 ...
 $ pri_nee_soc_3: int  3 6 4 3 5 3 4 6 2 6 ...
 $ pri_nee_soc_4: int  1 6 4 2 4 2 5 4 2 4 ...
 $ pri_nee_soc_5: int  1 4 4 5 4 2 6 6 3 6 ...
 $ pri_nee_soc_6: int  1 3 5 5 2 4 4 4 2 2 ...
 $ pri_nee_soc_7: int  1 1 3 3 1 2 2 6 1 2 ...
 $ pri_nee_soc_8: int  1 7 4 2 2 2 2 6 3 2 ...
 $ pri_nee_soc_9: int  1 3 4 2 6 5 6 7 1 6 ...
 $ pri_nee_int_1: int  1 1 4 4 2 4 2 5 2 5 ...
 $ pri_nee_int_2: int  1 6 5 5 1 2 5 5 1 3 ...
 $ pri_nee_int_3: int  7 7 5 5 6 2 4 3 3 6 ...
 $ pri_nee_int_4: int  3 6 2 7 5 5 4 4 4 6 ...
 $ pri_nee_int_5: int  5 6 4 7 2 5 2 3 6 6 ...
 $ pri_nee_int_6: int  3 6 3 5 2 3 3 2 3 3 ...
 $ pri_nee_int_7: int  7 7 5 6 2 5 6 6 6 4 ...
 $ pri_nee_int_8: int  1 7 4 5 5 3 5 5 6 3 ...
 $ pri_nee_int_9: int  4 7 3 3 5 5 5 5 4 3 ...
 $ soc_1        : int  5 5 3 2 2 3 2 5 3 2 ...
 $ soc_2        : int  4 4 6 6 6 6 5 2 6 6 ...
 $ soc_3        : int  4 4 2 3 2 2 5 6 4 6 ...
 $ soc_4        : int  4 6 4 7 6 6 3 5 3 4 ...
 $ soc_5        : int  7 5 2 6 4 2 2 4 2 3 ...
 $ soc_6        : int  4 5 6 5 2 6 2 4 3 4 ...
 $ soc_7        : int  3 2 2 2 2 2 2 5 3 2 ...
 $ soc_8        : int  3 4 6 6 5 4 2 2 7 5 ...
 $ itg_1        : int  1 1 2 3 2 3 1 4 3 1 ...
 $ itg_2        : int  2 1 4 4 4 6 2 4 1 1 ...
 $ itg_3        : int  5 7 4 5 4 5 4 4 7 1 ...
 $ itg_4        : int  2 7 6 2 6 6 7 4 3 7 ...
 $ itg_5        : int  1 1 2 1 2 2 1 4 1 1 ...
 $ itg_6        : int  4 1 2 3 2 2 4 4 2 1 ...
 $ itg_7        : int  1 6 2 2 3 2 1 4 6 1 ...
 $ itg_8        : int  5 2 4 5 4 4 6 4 3 1 ...
 $ itg_9        : int  5 1 1 2 6 5 2 4 7 2 ...
 $ itg_10       : int  5 2 2 7 6 5 7 4 7 6 ...
 $ itg_11       : int  4 4 4 5 5 5 6 4 4 1 ...
 $ anx_1        : int  1 1 3 5 5 2 6 5 3 6 ...
 $ anx_2        : int  5 4 3 1 5 6 3 3 5 5 ...
 $ anx_3        : int  1 1 5 3 3 2 6 3 2 6 ...
 $ anx_4        : int  4 3 3 3 3 3 5 1 7 2 ...
 $ anx_5        : int  6 6 2 5 5 3 6 3 1 2 ...
 $ anx_6        : int  6 7 3 3 5 6 2 5 6 3 ...
 $ anx_7        : int  3 6 5 6 4 2 2 1 2 5 ...
 $ anx_8        : int  6 4 4 3 5 7 4 6 7 2 ...
 $ ria_1        : int  1 7 5 5 6 3 4 3 7 6 ...
 $ ria_2        : int  5 7 5 4 4 6 6 5 6 6 ...
 $ ria_3        : int  1 6 5 6 6 3 3 5 5 3 ...
 $ ria_4        : int  6 3 3 4 5 5 3 4 6 6 ...
 $ ria_5        : int  4 2 5 6 4 2 6 6 5 5 ...
 $ ria_6        : int  5 6 3 3 5 6 2 3 4 5 ...
 $ ria_7        : int  5 7 5 4 5 5 1 7 5 6 ...
 $ ria_8        : int  6 7 5 5 5 6 6 5 4 6 ...
 $ tra_1        : int  5 7 3 3 2 5 3 4 4 5 ...
 $ tra_2        : int  6 2 6 6 6 4 6 4 7 5 ...
 $ tra_3        : int  5 7 4 3 5 5 5 4 5 5 ...
 $ tra_4        : int  7 6 5 7 4 5 6 4 5 2 ...
 $ tra_5        : int  5 7 4 3 5 5 2 4 4 6 ...
 $ tra_6        : int  7 1 4 6 6 5 6 4 6 2 ...
 $ tra_7        : int  4 7 4 3 5 4 2 4 2 6 ...
 $ tra_8        : int  3 7 4 3 4 5 5 4 5 6 ...

Alle Variablen liegen als integer vor. Für die Fragebogenitems (pri_nee_, soc_, itg_, anx_, ria_ und tra_), die intervallskaliert sein sollen, ist das korrekt. Die soziodemographischen Variablen male und inc hingegen sind nominal- bzw. ordinalskaliert. Das bedeutet, dass sie noch faktorisiert werden müssen, um in R als solche erkannt zu werden.

# nominalskaliert (unsortierter Faktor):
data$male <- factor(data$male)
str(data$male)
 Factor w/ 2 levels "0","1": 1 2 1 1 1 1 2 2 1 1 ...
exclamation
Nicht verwirren lassen: Der Faktor male hat die Kodierungen 0 und 1 (wie schon die integer-Variable vorher), aber die interne Kodierung des Faktors ist 1 und 2.
# ordinalskaliert (sortierter Faktor):
data$inc <- factor(data$inc, ordered=TRUE)
str(data$inc)
 Ord.factor w/ 5 levels "1"<"2"<"3"<"4"<..: 2 3 1 2 3 2 1 1 1 3 ...
levels(data$inc)
[1] "1" "2" "3" "4" "5"
exclamation
Aus dem Codebuch ist leider nicht ersichtlich, welche Kategorie (z.B. < $500) für welche Kodierung steht (z.B. 1). Wir gehen hier davon aus, dass beide aufsteigend gepaart wurden, z.B. < $500 = 1, aber die interne Kodierung eines Faktors beginnt bei 1, d.h. in unserem Fall gibt es 1 und 2.


4.) Wie heißt die Variable, die kodiert, inwieweit die befragte Person gerne viele Menschen um sich herum hat? Welche Antwortoption auf der Messskala (hiermit ist nicht die Kodierung der Daten gemeint) haben die meisten befragten Personen angekreuzt?

Tipp 1 Den Namen der Variablen sowie deren Messskala finden wir im Codebuch. Die Häufigkeiten der jeweiligen Ausprägungen der Variablen bringen wir in R in Erfahrung.
Tipp 2 Mit der Funktion table() können wir uns die Häufigkeiten der Ausprägungen einer Variablen ausgeben lassen. Die Funktion ist auch bereits sehr hilfreich, um einen schnellen Überblick über die möglichen Ausprägungen zu bekommen.

Lösung

Die Variable heißt soc_2 und hat eine Messskala, welche von -3 bis 3 (inklusive 0) geht (Codebuch S.20).

table(data$soc_2)

 1  2  3  4  5  6  7 
 2 14 36 69 72 61 27 

Die Kodierung 5 kommt am häufigsten vor. Die meisten befragten Personen haben damit eine 1 auf der Messskala angegeben.


5.) Gibt es Werte von Variablen im Datensatz, die unplausibel erscheinen? Wenn ja, entferne die entsprechenden Personen aus dem Datensatz.

Tipp 1 Hiervoll ist es sinnvoll, sich eine Übersicht der Ausprägungen aller Variablen anzuschauen und diese ggf. mit den Angaben im Codebuch zu vergleichen.
Tipp 2 Es gibt einen Wert einer Variablen der heraussticht.

Lösung
sapply(sapply(data, unique), sort, na.last=TRUE) # sortierte Ausprägungen der Variablen
$id
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
 [17]  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32
 [33]  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48
 [49]  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64
 [65]  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80
 [81]  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96
 [97]  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111 112
[113] 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
[129] 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
[145] 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
[161] 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
[177] 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
[193] 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
[209] 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
[225] 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
[241] 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
[257] 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
[273] 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
[289] 289 290 291 292 293 294 295 296

$male
[1] 0    1    <NA>
Levels: 0 1

$age
 [1]  9 18 19 20 21 22 23 28 29 56 NA

$inc
[1] 1    2    3    4    5    <NA>
Levels: 1 < 2 < 3 < 4 < 5

$time
  [1]      3      5      7      8      9     10     12     13     21
 [10]     31     86    129    165    194    240    259    313    351
 [19]    369    371    384    439    443    455    456    458    484
 [28]    539    562    585    587    593    601    602    606    624
 [37]    638    639    663    677    694    706    725    741    760
 [46]    778    814    815    828    829    840    847    851    852
 [55]    875    877    890    892    899    910    934    986    991
 [64]    992    999   1035   1039   1040   1043   1052   1056   1061
 [73]   1071   1073   1075   1077   1088   1090   1094   1097   1104
 [82]   1118   1119   1133   1141   1143   1144   1148   1152   1155
 [91]   1157   1158   1166   1167   1176   1177   1187   1197   1200
[100]   1209   1211   1219   1220   1222   1227   1236   1243   1248
[109]   1250   1255   1258   1259   1265   1290   1292   1303   1313
[118]   1314   1316   1318   1319   1332   1343   1345   1349   1363
[127]   1367   1372   1376   1387   1388   1397   1402   1405   1411
[136]   1414   1419   1425   1438   1448   1453   1460   1465   1481
[145]   1492   1496   1497   1499   1514   1524   1525   1560   1581
[154]   1595   1596   1602   1606   1625   1628   1633   1651   1655
[163]   1656   1660   1669   1671   1672   1683   1695   1702   1706
[172]   1713   1714   1716   1732   1734   1735   1745   1753   1756
[181]   1772   1778   1780   1803   1806   1815   1820   1831   1845
[190]   1847   1869   1879   1889   1905   1930   1932   1945   1949
[199]   1985   1994   2022   2077   2125   2135   2139   2142   2144
[208]   2183   2185   2197   2248   2255   2319   2342   2348   2360
[217]   2373   2393   2420   2447   2456   2493   2495   2515   2518
[226]   2523   2537   2597   2606   2649   2654   2673   2759   2769
[235]   2927   3204   3224   3273   3386   3466   3739   3803   3808
[244]   3858   3913   4084   4436   4702   4748   5031   5108   5229
[253]   5469   5927   5944   6064   6282   6598   6685   6849   7129
[262]   7246   8016   8817   9274  12533  13928  17371  17973  22834
[271]  50047  54973  96391 101191 110358 192301 197593 342508 590589
[280] 688498

$pri_nee_gen_1
[1]  1  2  3  4  5  6  7 NA

$pri_nee_gen_2
[1]  1  2  3  4  5  6  7 NA

$pri_nee_gen_3
[1]  2  3  4  5  6  7 NA

$pri_nee_gen_4
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_1
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_2
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_3
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_4
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_5
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_6
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_7
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_8
[1]  1  2  3  4  5  6  7 NA

$pri_nee_soc_9
[1]  1  2  3  4  5  6  7 NA

$pri_nee_int_1
[1]  1  2  3  4  5  6 NA

$pri_nee_int_2
[1]  1  2  3  4  5  6  7 NA

$pri_nee_int_3
[1]  1  2  3  4  5  6  7 NA

$pri_nee_int_4
[1]  1  2  3  4  5  6  7 NA

$pri_nee_int_5
[1]  1  2  3  4  5  6  7 NA

$pri_nee_int_6
[1]  1  2  3  4  5  6  7 NA

$pri_nee_int_7
[1]  1  2  3  4  5  6  7 NA

$pri_nee_int_8
[1]  1  2  3  4  5  6  7 NA

$pri_nee_int_9
[1]  1  2  3  4  5  6  7 NA

$soc_1
[1]  1  2  3  4  5  6  7 NA

$soc_2
[1]  1  2  3  4  5  6  7 NA

$soc_3
[1]  1  2  3  4  5  6  7 NA

$soc_4
[1]  1  2  3  4  5  6  7 NA

$soc_5
[1]  1  2  3  4  5  6  7 NA

$soc_6
[1]  1  2  3  4  5  6  7 NA

$soc_7
[1]  1  2  3  4  5  6  7 NA

$soc_8
[1]  1  2  3  4  5  6  7 NA

$itg_1
[1]  1  2  3  4  5  6 NA

$itg_2
[1]  1  2  3  4  5  6  7 NA

$itg_3
[1]  1  2  3  4  5  6  7 NA

$itg_4
[1]  1  2  3  4  5  6  7 NA

$itg_5
[1]  1  2  3  4  5  6  7 NA

$itg_6
[1]  1  2  3  4  5  6  7 NA

$itg_7
[1]  1  2  3  4  5  6  7 NA

$itg_8
[1]  1  2  3  4  5  6  7 NA

$itg_9
[1]  1  2  3  4  5  6  7 NA

$itg_10
[1]  1  2  3  4  5  6  7 NA

$itg_11
[1]  1  2  3  4  5  6  7 NA

$anx_1
[1]  1  2  3  4  5  6  7 NA

$anx_2
[1]  1  2  3  4  5  6  7 NA

$anx_3
[1]  1  2  3  4  5  6  7 NA

$anx_4
[1]  1  2  3  4  5  6  7 NA

$anx_5
[1]  1  2  3  4  5  6  7 NA

$anx_6
[1]  1  2  3  4  5  6  7 NA

$anx_7
[1]  1  2  3  4  5  6  7 NA

$anx_8
[1]  1  2  3  4  5  6  7 NA

$ria_1
[1]  1  2  3  4  5  6  7 NA

$ria_2
[1]  1  2  3  4  5  6  7 NA

$ria_3
[1]  1  2  3  4  5  6  7 NA

$ria_4
[1]  1  2  3  4  5  6  7 NA

$ria_5
[1]  1  2  3  4  5  6  7 NA

$ria_6
[1]  1  2  3  4  5  6  7 NA

$ria_7
[1]  1  2  3  4  5  6  7 NA

$ria_8
[1]  1  2  3  4  5  6  7 NA

$tra_1
[1]  1  2  3  4  5  6  7 NA

$tra_2
[1]  1  2  3  4  5  6  7 NA

$tra_3
[1]  1  2  3  4  5  6  7 NA

$tra_4
[1]  1  2  3  4  5  6  7 NA

$tra_5
[1]  1  2  3  4  5  6  7 NA

$tra_6
[1]  1  2  3  4  5  6  7 NA

$tra_7
[1]  1  2  3  4  5  6  7 NA

$tra_8
[1]  1  2  3  4  5  6  7 NA
which(data$age == 9)
[1] 232

Die Person mit der Zeile 232 hat (vermutlich versehentlich) als Alter 9 Jahre angegeben. Wir entfernen diese Person aus dem Datensatz.

data <- data[-which(data$age == 9),]


6.) Enthält der Datensatz fehlende Werte (“Missings”; NA) und wenn ja, wie viele insgesamt und auf welchen Variablen?

Tipp Das Thema “Fehlende Werte” wird im Kapitel zur Datenvorbereitung nur kurz angerissen, weil es ein eigenständiges Kapitel dazu gibt.

Lösung
anyNA(data) # prüft ob mind. ein Missing im Datensatz
[1] TRUE

Ja, data enthält fehlende Werte.

table(is.na(data)) # absolute Anzahl fehlender Werte

FALSE  TRUE 
19337  1313 
table(is.na(data))[2]/(table(is.na(data))[1] + table(is.na(data))[2]) 
# relative Anzahl fehlender Werte
      TRUE 
0.06358354 
colSums(is.na(data)) # Übersicht über Anzahl Missings für alle Variablen
           id          male           age           inc          time 
            0            24            25            28             0 
pri_nee_gen_1 pri_nee_gen_2 pri_nee_gen_3 pri_nee_gen_4 pri_nee_soc_1 
           19            19            19            19            19 
pri_nee_soc_2 pri_nee_soc_3 pri_nee_soc_4 pri_nee_soc_5 pri_nee_soc_6 
           19            19            19            19            19 
pri_nee_soc_7 pri_nee_soc_8 pri_nee_soc_9 pri_nee_int_1 pri_nee_int_2 
           19            19            19            21            21 
pri_nee_int_3 pri_nee_int_4 pri_nee_int_5 pri_nee_int_6 pri_nee_int_7 
           21            21            21            21            21 
pri_nee_int_8 pri_nee_int_9         soc_1         soc_2         soc_3 
           21            21            15            15            15 
        soc_4         soc_5         soc_6         soc_7         soc_8 
           15            15            16            15            15 
        itg_1         itg_2         itg_3         itg_4         itg_5 
           21            21            21            21            21 
        itg_6         itg_7         itg_8         itg_9        itg_10 
           21            21            21            21            21 
       itg_11         anx_1         anx_2         anx_3         anx_4 
           21            18            18            18            18 
        anx_5         anx_6         anx_7         anx_8         ria_1 
           18            18            18            18            17 
        ria_2         ria_3         ria_4         ria_5         ria_6 
           17            17            17            17            17 
        ria_7         ria_8         tra_1         tra_2         tra_3 
           17            17            21            21            21 
        tra_4         tra_5         tra_6         tra_7         tra_8 
           21            21            21            21            21 

Jede Variable mit Ausnahme von id und time enthält fehlende Werte.


7.) Was ist die höchste Anzahl an fehlenden Werten von einer Person und welche Person hat bzw. welche Personen haben die meisten fehlenden Werte?

Tipp In der letzten Aufgabe haben wir uns variablenweise Missings angeschaut mit colSums(). Nun wollen wir uns zeilenweise Missings anschauen.

Lösung
max(rowSums(is.na(data))) # maximale Anzahl Missings (absoluter Wert)
[1] 68
max(rowSums(is.na(data))) / ncol(data)
# Max-Anzahl Missings einer Person / Anzahl aller Variablen (relativer Wert)
[1] 0.9714286

Fehlende Werte auf 68 Variablen ist die Höchstzahl an fehlenden Werten pro Person. Das entspricht einem Prozentsatz von ca. 97% fehlenden Werten.

# Personen mit diesen Zeilen haben die meisten Missings:
names(which(rowSums(is.na(data)) == max(rowSums(is.na(data)))))
 [1] "63"  "66"  "78"  "133" "134" "136" "139" "180" "199" "206" "262"
[12] "267" "268" "281" "283"

Wir müssen hier names() nutzen, damit wir die Zeilennamen ausgegeben bekommen da wir sonst einen benannten Vektor ausgegeben bekommen.

Man sollte überlegen, wie mit den Daten dieser 15 Personen bei etwaigen Analysen umzugehen wäre. Wenn die Daten MCAR sind, könnten wir diese Personen aus den Analysen entfernen. Mehr Infos zu Fehlenden Werten im gleichnamigen Kapitel.


Übung 2: Extrahieren von Daten

Nun wollen wir einzelne Daten aus dem Datensatz extrahieren. Dabei interessieren uns entweder Variablen mit bestimmten Ausprägungen (von Personen) oder Personen mit bestimmten Ausprägungen (auf Variablen).

exclamation Achte darauf, immer auch die id-Variable mit zu extrahieren, um Beobachtungseinheiten identifizieren zu können, auch wenn das nicht jedes mal erneut in der Aufgabenbeschreibung steht.

1.) Extrahiere alle demographischen Variablen aus data.

Tipp 1

Im Codebuch (S. 26ff) steht, welche Variablen zu den demographischen Angaben zählen.

exclamation
Im Codebuch steht die Variable sex, welche im Datensatz nicht enthalten ist. Alternativ gibt es die Variable male.

Tipp 2 Es gibt drei demographische Variablen in data (aber mehr im Codebuch).

Lösung
library(dplyr)
select(data, id, male, age, inc)


2.) Extrahiere alle Variablen, die grundlegende Bedürfnisse (General Needs) erfassen.

Tipp 1 Die Variablen haben denselben Wortstamm: gen.
Tipp 2 Es gibt vier Items zu grundlegenden Bedürfnissen.

Lösung
data[,c(1, # id
        grep("gen", names(data)))] # general needs


3.) Extrahiere alle Variablen, die gesellschaftliche (Societal Needs) und interpersonelle (Interpersonal Needs) Bedürfnisse erfassen.

Tipp 1 Die Variablen haben zwar denselben Wortstamm – nee – aber den haben die Variablen zu grundlegenden Bedürfnissen (General Needs) auch.
Tipp 2 Es gibt insgesamt 18 Items zu gesellschaftlichen und interpersonellen Bedürfnissen (jeweils 9).

Lösung
# Vorauswahl von Bedürfnis-Variablen mittels des gemeinsamen Wortstammes:
all_needs <- data[,c(1, # id
                     grep("nee", names(data)))] # alle Bedürfnis-Variablen
# Auswahl der gewollten Variablen aus den Bedürfnis Variablen (neben "id") ..
# .. solche, die "c" oder "t" im Namen haben (trifft nur auf General needs nicht zu):
all_needs[grep("id|c|t", names(all_needs))]


4.) Extrahiere alle Personen, die weniger als $500 oder mehr als $5.000 monatlich zur Verfügung haben.

Tipp Um beide Bedingungen (< $500 und > $5.000) abzufragen, können wir den logischen Operator | (“oder”) nutzen.

Lösung

Zuerst vergleichen wir die Angaben zu den Ausprägungen von inc im Codebuch (S. 28) und der Kodierung in R. Laut Codebuch ist < $500 die erste Ausprägung; > $5.000 die letzte. Nun schauen wir, mit welchen Kodierungen diese korrespondieren.

table(data$inc)

  1   2   3   4   5 
148  74  24  15   6 

DIe beiden werden mit 1 und 5 kodiert. Anschließend wenden wir dieses Wissen auf unsere Selektion an.

filter(data, inc == 1 | inc == 5)


5.) Extrahiere die “Extremkreuzer” (Personen, die nur die niedrigste oder höchste Ausprägung einer Frage ankreuzen) aus dem Geselligkeits-Fragebogen (Sociability).

Tipp 1 Wir können wieder den logischen Operator | (“oder”) nutzen, um jeweils Personen mit der niedrigste oder höchsten Ausprägung eines Items auszuwählen.
Tipp 2 Es gibt insgesamt zwei Extremkreuzer.

Lösung

Im Codebuch (S. 20) sehen wir, dass für alle Items des Geselligkeits-Fragebogen dieselbe Skale, welche von -3 bis 3 geht, genutzt wurde. Nun schauen wir uns am Beispiel eines Items an, wie diese in R kodiert werden.

# niedrigste und höchste Ausprägung in Erfahrung bringen:
table(data$soc_1)

 1  2  3  4  5  6  7 
23 71 54 55 52 21  4 
# Fall-Selektion anwenden:
filter(data, soc_1 == 1 | soc_1 == 7,
             soc_2 == 1 | soc_2 == 7,
             soc_3 == 1 | soc_3 == 7,
             soc_4 == 1 | soc_4 == 7,
             soc_5 == 1 | soc_5 == 7,
             soc_6 == 1 | soc_6 == 7,
             soc_7 == 1 | soc_7 == 7,
             soc_8 == 1 | soc_8 == 7)

Auf den Seiten 6 bis 7 sehen wir die Items des Geselligkeits-Fragebogens (oben rechts ist der Pfeil).


6.) Extrahiere die Items des Fragebogens zu Integrität (Integrity) für alle Personen, die 18 Jahre alt sind.

Tipp 1 Die Reihenfolge der Auswahl, d.h. ob zuerst Variablen oder zuerst Fälle selektiert werden, ist eigentlich irrelevant, aber wenn wir erst die Fälle selektieren und dann die Variablen müssen wir die Variable age nicht wieder aus dem finalen Datensatz entfernen.
Tipp 2 Der finale Datensatz besteht aus 12 Variablen (davon sind 11 die Integritäts-Items) von 54 Personen.

Lösung
# Fälle selektieren:
data_18 <- filter(data, age == 18)
# Variablen selektietren:
all_itg_items <- data_18[,c(1, # id
                         grep("itg", names(data_18)))] # Integrität Items


7.) Extrahiere alle Personen, die im Fragebogen zu interpersonellen Bedürfnissen (Needs, Interpersonal) über dem Gesamtmittelwert (Mittelwert über alle Personen im Datensatz) liegen. Entferne Personen mit mindestens einem fehlenden Wert auf diesen Items aus der Analyse.

exclamation Unser Vorgehen mit fehlenden Wert hier (casewise deletion) ist stark vereinfacht und sollte in echten Analysen nicht ohne Belege für MCAR durchgeführt werden.

Tipp 1 Wir müssen
1) alle Items des Fragebogens extrahieren,
2) alle Personen mit mind. einem Missing entfernen,
3) die Items jeweils für jede Person aufsummieren (d.h. individuelle Scores bilden),
4) diese individuellen Scores über alle Personen aufsummieren, um den Gesamtmittelwert zu berechnen,
5) die individuellen Scores mit dem Gesamtmittelwert vergleichen, um nur überdurchschnittliche Personen in unserer finalen Auswahl zu haben.
Tipp 2 Im finalen Datensatz befinden sich 140 (von initial 296) Personen.

Lösung
# 1) Items extrahieren:
all_int_items <- data[,c(1, # id
                         grep("int", names(data)))] # Int. Bedürfnisse Items
# 2) Personen mit mind. einem Missing entfernen:
all_int_items <- na.omit(all_int_items) # 21 Personen entfernt
# 3) individuelle Scores bilden:
library(dplyr)
all_int_items <- mutate(all_int_items, score = rowSums(all_int_items))
# 4) Mittelwert individueller Scores berechnen:
mean_score <- mean(all_int_items$score)
mean_score
[1] 182.6387
# 5) überdurchschnittliche Personen extrahieren:
final_data <- filter(all_int_items, score > mean_score) # 135 Personen entfernt


Übung 3: Sortieren von Daten

Im Folgenden wollen wir unseren Datensatz nach den aufsteigenden bzw. absteigenden Ausprägungen auf einer der enthaltenen Variablen sortieren.

1.) Sortiere data (primär) nach den aufsteigenden Ausprägungen in age und (sekundär) nach dem Geschlecht (Frauen zuerst).

exclamation Da die Kodierung der Variablen male im Codebuch nicht geklärt wird, gehen wir hier standarmäßig davon aus, dass 0 für nein und 1 für ja steht.

Lösung

Da Frauen zuerst in der sekundären Sortierung vorkommen sollen, können wir beide Variablen aufsteigend sortieren.

data[order(data$age, data$male),] # Default: aufsteigende Sortierung


2.) Sortiere data (primär) nach absteigendem Einkommen und (sekundär, tertiär, ect.) nach den aufsteigenden Ausprägungen auf den Traditionalismus-Items (Traditionalism) in ihrer natürlichen Reihenfolge (beginnend bei _1, endend bei _8).

Tipp 1 Mit der Funktion order() können wir nur jeweils auf- oder absteigend für alle angegebenen Variablen sortieren. Daher sollten wir für diese Aufgabe auf andere Funktionen, z.B. arrange() aus dem Paket dplyr zurückgreifen.
Tipp 2 Um besser beurteilen zu können, ob die Sortierung erfolgreich war, ist es sinnvoll, zuerst einen neuen Datensatz nur aus den relevanten Variablen (inklusive id) zu erstellen.

Lösung
library(dplyr)
# neuer Datensatz nur mit relevanten Variablen:
data_tra <- data[,c(1, # id
                    4, # inc
                    grep("tra", names(data)))]
# Sortierung:
arrange(data_tra, -inc, tra_1, tra_2, tra_3, tra_4, tra_5, tra_6, tra_7, tra_8)
# mit einem "-" sortieren wir absteigend


Übung 4: Änderung der Kodierung von Daten

Nun wollen wir die Kodierungen einiger Variablen ändern bzw. Variablen mit neuen Kodierungen erstellen.

1.) Erstelle eine neue Variable income, die das monatliche Einkommen der befragten Personen kodiert, und dafür die Kategorien aus dem Codebuch (S.28) nutzt.

Tipp Um besser beurteilen zu können, ob die Kodierung erfolgreich war, ist es sinnvoll, zuerst einen neuen Datensatz bestehend aus inc und id zu erstellen.

Lösung
# neuen Datensatz erstellen:
library(dplyr)
data_inc <- select(data, id, inc)
# neue Variable income erstellen:
rec <- c("1='<$500'; 2='$500-$1000'; 3='$1000-$2000'; 4='$2000-$4000'; 5='>$5000'")
library(car)
data_inc$income <- recode(data_inc$inc, recodes=rec)

Die Variable rec, welche die Überführung der bestehenden in die neue Kodierung enthält, wurde nur aus darstellerischen Gründen erstellt. Der Inhalt kann auch direkt dem Parameter recodes übergeben werden.


2.) Erstelle eine neue Variable sex, die analog zur gleichnamigen Variablen im Codebuch das biologische Geschlecht kodiert. Gehe für diese Aufgabe davon aus, dass alle Personen, die einen fehlender Wert auf male haben, einer Kategorie other (nicht-binäres Geschlecht) zugeordnet werden.

Tipp Um besser beurteilen zu können, ob die Kodierung erfolgreich war, ist es sinnvoll, zuerst einen neuen Datensatz bestehend aus male und id zu erstellen.

Lösung
library(dplyr)
# neuen Datensatz erstellen:
data_sex <- select(data, id, male)
# neue Variable sex erstellen:
data_sex$sex <- case_when(data_sex$male == 0 ~ "female",
                          data_sex$male == 1 ~ "male",
                          is.na(data_sex$male) ~ "other")


3.) Rekodiere die negativ kodierten Items des Fragebogens zu Risikovermeidung (Risk Avoidance).

Tipp 1 Die negativ kodierten Items sind im Codebuch jeweils mit einem * markiert.
Tipp 2 Es ist sinnvoll zur Überprüfung der Aufgabe, einen neuen Datensatz bestehend aus den negativ kodierten Items und ihrem rekodierten Pendant (und natürlich id) zu erstellen.

Lösung
# neuen Datensatz erstellen:
library(dplyr)
data_ria <- select(data, id, 
                   ria_1, ria_3, ria_5) # negativ kodierte Items
# neue rekodierte Variablen erstellen:
library(car)

data_ria$ria_1_rec <- recode(data_ria$ria_1, recodes="1=7; 2=6; 3=5; 4=4; 5=3; 6=2; 7=1")
data_ria$ria_3_rec <- recode(data_ria$ria_3, recodes="1=7; 2=6; 3=5; 4=4; 5=3; 6=2; 7=1")
data_ria$ria_5_rec <- recode(data_ria$ria_5, recodes="1=7; 2=6; 3=5; 4=4; 5=3; 6=2; 7=1")


Übung 5: Erstellen von Summary-Variablen

Nachfolgend wollen wir neue Variablen erstellen, die Informationen aus mehreren Variablen des Datensatzes zusammenfassen.

1.) Erstelle für die verschiedenen Bereiche von Bedürfnissen – Allgemein (General), Gesellschaftlich (Societal) und Interpersonell (Interpersonal) – jeweils separate Summenwerte und einen Gesamtsummenwert (über alle drei Bereiche).

Tipp Die Items aller drei Bedürfnis-Bereiche haben denselben Wortstamm: nee.

Lösung
# neuer Datensatz mit relevanten Variablen:
data_need <- data[,c(1, # id
                     grep("nee", names(data)))] # Bedürfnis-Items

# Summenwerte der drei Bedürfnis-Bereiche und Gesamtsummenwert:
library(dplyr)
data_need$score_gen <- rowSums(select(data_need, matches("nee_gen")))
data_need$score_soc <- rowSums(select(data_need, matches("nee_soc")))
data_need$score_int <- rowSums(select(data_need, matches("nee_int")))
data_need$score_all <- rowSums(select(data_need, matches("nee")))


2.) Erstelle die personenspezifischen Summenwerte der Items, die interpersonelle Bedürfnisse erfassen (Needs, Interpersonal), für alle Personen, die ein monatliches Einkommen von mehr als $1.000 haben. Bei allen Personen, die weniger zur Verfügung haben, soll ein "/" in der Summenwert-Variablen stehen.

Tipp Zur Bearbeitung der Aufgabe können wir mutate() mit ifelse() kombinieren, um den beiden Bedingungen (monatliches Einkommen von mehr bzw. weniger als $1.000) unterschiedliche Werte zuzuweisen.

Lösung
# neuer Datensatz mit relevanten Variablen:
data_int <- data[,c(1, # id
                    4, # inc
                     grep("int", names(data)))] # Int. Bedürfnisse Items

Nun vergleichen wir die Angaben zu den Ausprägungen von inc im Codebuch (S. 28) und der Kodierung in R. Es gibt insgesamt 5 Ausprägungen. Auf unsere Bedingung (mehr als $1.000) treffen drei Ausprägungen zu. Daher ist es codesparender, wenn wir die zwei nicht zutreffenden Ausprägungen (< $500 und $500 - $1000) negieren (!=). Laut Codebuch ist < $500 die erste Ausprägung; $500 - $1000 die zweite. Nun schauen wir, mit welchen Kodierungen diese korrespondieren.

table(data$inc)

  1   2   3   4   5 
148  74  24  15   6 

Sie haben die Kodierungen 1 und 2. Diese Information können wir nun anwenden.

# neue Variable mit Summenwert bzw. "/" erstellen
library(dplyr)
data_int$score <- ifelse(data_int$inc != 1 & data_int$inc != 2,
                         rowSums(select(data_need, matches("int"))),
                         "/") # ifelse(Bedingung, trifft zu, trifft nicht zu)



Um eine möglichst exakte Replikation der Funktionen zu gewährleisten gibt es im folgenden relevante Angaben zum System (R-Version, Betriebssystem, geladene Pakete mit Angaben zur Version), mit welchem diese Seite erstellt wurde.

R version 4.0.3 (2020-10-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.2 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0

locale:
 [1] LC_CTYPE=de_DE.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=de_DE.UTF-8        LC_COLLATE=de_DE.UTF-8    
 [5] LC_MONETARY=de_DE.UTF-8    LC_MESSAGES=de_DE.UTF-8   
 [7] LC_PAPER=de_DE.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
[1] car_3.0-10       carData_3.0-4    dplyr_1.0.4     
[4] rmarkdown_2.7    kableExtra_1.3.4

loaded via a namespace (and not attached):
 [1] tidyselect_1.1.0  xfun_0.21         bslib_0.2.4      
 [4] purrr_0.3.4       haven_2.3.1       colorspace_2.0-0 
 [7] vctrs_0.3.6       generics_0.1.0    htmltools_0.5.1.1
[10] viridisLite_0.3.0 yaml_2.2.1        utf8_1.1.4       
[13] rlang_0.4.10      jquerylib_0.1.3   pillar_1.5.0     
[16] foreign_0.8-79    glue_1.4.2        readxl_1.3.1     
[19] lifecycle_1.0.0   stringr_1.4.0     cellranger_1.1.0 
[22] munsell_0.5.0     rvest_0.3.6       zip_2.1.1        
[25] evaluate_0.14     knitr_1.31        rio_0.5.16       
[28] forcats_0.5.1     curl_4.3          fansi_0.4.2      
[31] highr_0.8         Rcpp_1.0.6        scales_1.1.1     
[34] webshot_0.5.2     jsonlite_1.7.2    abind_1.4-5      
[37] systemfonts_1.0.1 distill_1.2       hms_1.0.0        
[40] digest_0.6.27     stringi_1.5.3     openxlsx_4.2.3   
[43] cli_2.3.0         tools_4.0.3       magrittr_2.0.1   
[46] sass_0.3.1        tibble_3.0.6      crayon_1.4.1     
[49] pkgconfig_2.0.3   downlit_0.2.1     ellipsis_0.3.1   
[52] data.table_1.14.0 xml2_1.3.2        assertthat_0.2.1 
[55] svglite_2.0.0     httr_1.4.2        rstudioapi_0.13  
[58] R6_2.5.0          compiler_4.0.3   

Für Informationen zur Interpretation dieses Outputs schaut auch den Abschnitt Replizierbarkeit von Analysen des Kapitels zu Paketen an.

jump-to-top

feedback-r-lernplattform