Explorative Datenanalyse mit
R The R Bootcamp |
adapted from trueloveproperty.co.uk
In diesem Practical wirst du das Transformieren, Gruppieren und
Analysieren von Daten mit dplyr
üben.
Am Ende des Practicals wirst du wissen wie man:
Öffne dein TheRBootcamp
R project. Es sollte bereits
die Ordner 1_Data
und 2_Code
enthalten.
Öffne ein neues R Skript. Schreibe deinen Namen, das Datum und “Wrangling II Practical” als Kommentare an den Anfang des Skripts.
## NAME
## DATUM
## Wrangling II Practical
Speichere das neue Skript unter dem Namen
wrangling_II_practical.R
im 2_Code
Ordner.
Lade das tidyverse
.
# Pakete laden
library(tidyverse)
library(tidyverse)
In diesem Abschnitt arbeitest du zunächst mit dem
bevoelkerung.csv
Datensatz. Er enthält die Einwohnerzahlen
verschiedener Schweizer Städte von 1930 bis 2011. Im
Datensätze
Tab findest du eine Auflistung und eine kurze
Beschreibung der im Datensatz enthaltenen Variablen.
read_csv()
Funktion in R ein
und speichere ihn unter dem Namen bevoelkerung
.bevoelkerung <- read_csv(file = "1_Data/bevoelkerung.csv")
print()
) und die Variablennamen
(names()
) anschaust.names(bevoelkerung)
[1] "Stadtname" "st_wbev_2011" "st_wbev_2001"
[4] "proz_ver-2001–2011" "bevdichte" "st_wbev_1930"
[7] "st_wbev_1970" "st_wbev_1980" "st_wbev_1990"
[10] "st_wbev_2000"
bevoelkerung
# A tibble: 161 × 10
Stadtname st_wbev_2011 st_wbev_2001 `proz_ver-2001–2… bevdichte st_wbev_1930
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Basel 164516 164665 -0.1 69 148063
2 Bern 125681 122211 2.8 24 111783
3 Genève 188234 175697 7.1 119 124121
4 Lausanne 129383 115272 12.2 31 75915
5 Winterthur 103075 89484 15.2 15 53925
6 Zürich 376990 340197 10.8 43 290937
7 Biel-Bien… 51635 48142 7.3 24 37726
8 Lugano 55151 50877 8.4 17 17672
9 Luzern 78093 73233 6.6 27 47066
10 St. Gallen 73505 69857 5.2 19 63947
# … with 151 more rows, and 4 more variables: st_wbev_1970 <dbl>,
# st_wbev_1980 <dbl>, st_wbev_1990 <dbl>, st_wbev_2000 <dbl>
pivot_longer()
um das Format zu wechseln. Verwende
"st_wbev_2011"
und "st_wbev_2001"
für das
cols
Argument und "jahr" für
das
names_to
Argument und speichere das Resultat als neues
Objekt bevoelkerung_long
ab.# Transofmation vom Wide ins Long Format
bevoelkerung_long <- bevoelkerung %>%
pivot_longer(cols = c("XX", "XX"), names_to = "XX")
# Transofmation vom Wide ins Long Format
bevoelkerung_long <- bevoelkerung %>%
pivot_longer(cols = c("st_wbev_2011", "st_wbev_2001"), names_to = "jahr")
Printe den neu erstellten Datensatz. Alles wie erwartet?
Nun bringe nicht nur die Jahre 2001 und 2011, sondern alle im
Datensatz vorhandenen Jahre ins Long-Format. Schaue dir zunächst
nochmals die Namen der Spalten mit names()
an.
names(bevoelkerung)
[1] "Stadtname" "st_wbev_2011" "st_wbev_2001"
[4] "proz_ver-2001–2011" "bevdichte" "st_wbev_1930"
[7] "st_wbev_1970" "st_wbev_1980" "st_wbev_1990"
[10] "st_wbev_2000"
st_wbev_XXX
. Das bedeutet, dass du die sehr hilfreiche
starts_with()
Funktion zur Variablenauswahl verwenden
kannst. Benutze pivot_longer()
und
starts_with()
um alle Jahr-Variablen zu
transformieren.# Transofmation vom Wide ins Long Format
bevoelkerung_long <- bevoelkerung %>%
pivot_longer(cols = starts_with("XX"), names_to = "XX")
bevoelkerung_long <- bevoelkerung %>%
pivot_longer(cols = starts_with("st_"), names_to = "jahr")
Printe nochmals bevoelkerung_long
.
Die Einwohnerzahl ist im neuen Datensatz mi dem Standardwert
value
benannt. Führe nun nochmal die
pivot_longer
Funktion aus, verwende nun aber auch noch das
values_to
Argument um die neue Spalte
einwohner
zu nennen.
# Transofmation vom Wide ins Long Format
bevoelkerung_long <- bevoelkerung %>%
pivot_longer(cols = starts_with("XX"), names_to = "XX", values_to = "XX")
bevoelkerung_long <- bevoelkerung %>%
pivot_longer(cols = starts_with("st_"), names_to = "jahr", values_to = "einwohner")
Schaue dir das Resultat an. Alles in Ordnung?
Verwende nun das names_prefix
Argument um die
Präfixe der Jahreszahlen ("st_wbev_"
) automatisch zu
entfernen. Der character
-String der für
names_prefix
bereit gestellt wird, wird vom Beginn der
Variablennamen entfernt.
bevoelkerung_long <- bevoelkerung %>%
pivot_longer(starts_with("st_"), names_to = "jahr",
values_to = "einwohner",
names_prefix = "st_wbev_")
bevoelkerung_long
im
Long Format bekommen hättest und sie ins Wide Format umwandeln müsstest.
Verwende die pivot_wider()
Funktion und weise den
Argumenten names_from
und values_from
die
Spalten jahr
und einwohner
zu. Speichere das
Ergebnis als bevoelkerung_wide
ab.# Transofmation vom Long ins Wide Format
bevoelkerung_wide <- bevoelkerung_long %>%
pivot_wider(names_from = XX, values_from = XX)
bevoelkerung_wide <- bevoelkerung_long %>%
pivot_wider(names_from = jahr, values_from = einwohner)
Vergleiche bevoelkerung_wide
mit
bevoelkerung
. War die Rücktransformation erfolgreich? Was
fehlt?
Um die zuvor entfernten Präfixe wieder bei den Variablennamen
hinzuzufügen, kannst du das names_prefix
argument in
pivot_wider()
verwenden. Benutze names_prefix
um "st_wbev_"
als Präfix wieder hinzuzufügen.
bevoelkerung_wide <- bevoelkerung_long %>%
pivot_wider(names_from = jahr, values_from = einwohner,
names_prefix = "st_wbev_")
Im Rest des Practicals arbeitst du mit dem kc_house.csv
Datensatz. Er enthält Verkaufspreise von Häusern in King County,
Washington. Aufgelistet sind Häuser, welche zwischen Mai 2014 und Mai
2015 verkauft wurden. Nebst den Verkaufspreisen enthält der Datensatz
Spezifikationen der Häuser, z.B. die Anzahl Zimmer eines Hauses.
read_csv()
Funktion in R ein
und speichere ihn unter dem Namen kc_house
.kc_house <- read_csv(file = "1_Data/kc_house.csv")
summary()
und
names()
um einen Eindruck über dessen Struktur zu
erhalten.kc_house
# A tibble: 21,613 × 11
preis schlafzimmer badezimmer qf_wohnraum qf_parzelle stoecke ufer
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 221900 3 1 1180 5650 1 0
2 538000 3 2.25 2570 7242 2 0
3 180000 2 1 770 10000 1 0
4 604000 4 3 1960 5000 1 0
5 510000 3 2 1680 8080 1 0
6 1225000 4 4.5 5420 101930 1 0
7 257500 3 2.25 1715 6819 2 0
8 291850 3 1.5 1060 9711 1 0
9 229500 3 1 1780 7470 1 0
10 323000 3 2.5 1890 6560 2 0
# … with 21,603 more rows, and 4 more variables: qf_dachstock <dbl>,
# qf_keller <dbl>, baujahr <dbl>, postleitzahl <dbl>
summary(kc_house)
preis schlafzimmer badezimmer qf_wohnraum
Min. : 75000 Min. : 0.0 Min. :0.00 Min. : 290
1st Qu.: 321950 1st Qu.: 3.0 1st Qu.:1.75 1st Qu.: 1427
Median : 450000 Median : 3.0 Median :2.25 Median : 1910
Mean : 540088 Mean : 3.4 Mean :2.11 Mean : 2080
3rd Qu.: 645000 3rd Qu.: 4.0 3rd Qu.:2.50 3rd Qu.: 2550
Max. :7700000 Max. :33.0 Max. :8.00 Max. :13540
qf_parzelle stoecke ufer qf_dachstock qf_keller
Min. : 520 Min. :1.00 Min. :0.000 Min. : 290 Min. : 0
1st Qu.: 5040 1st Qu.:1.00 1st Qu.:0.000 1st Qu.:1190 1st Qu.: 0
Median : 7618 Median :1.50 Median :0.000 Median :1560 Median : 0
Mean : 15107 Mean :1.49 Mean :0.008 Mean :1788 Mean : 292
3rd Qu.: 10688 3rd Qu.:2.00 3rd Qu.:0.000 3rd Qu.:2210 3rd Qu.: 560
Max. :1651359 Max. :3.50 Max. :1.000 Max. :9410 Max. :4820
baujahr postleitzahl
Min. :1900 Min. :98001
1st Qu.:1951 1st Qu.:98033
Median :1975 Median :98065
Mean :1971 Mean :98078
3rd Qu.:1997 3rd Qu.:98118
Max. :2015 Max. :98199
qm_wohnraum
, qm_dachstock
und
qm_keller
, welche die jeweilige Raumgrösse in Quadratmeter
angeben. Ein Quadratfuss entspricht 0.093 Quadratmeter.kc_house <- kc_house %>%
mutate(XX = XX * 0.093,
XX = XX * 0.093,
XX = XX * 0.093)
kc_house <- kc_house %>%
mutate(qm_wohnraum = qf_wohnraum * 0.093,
qm_dachstock = qf_dachstock * 0.093,
qm_keller = qf_keller * 0.093)
mutate()
eine neue Spalte
qm_total
, welche die Summe aus qm_wohnraum
,
qm_dachstock
und qm_keller
darstellt.kc_house <- kc_house %>%
mutate(qm_total = qm_wohnraum + qm_dachstock + qm_keller)
villa
hinzu (mit
mutate()
), welche den Wert "ja"
annimmt, wenn
qm_total
grösser als 750 ist und “nein”, wenn
qm_total
kleiner oder gleich 750 ist.kc_house <- kc_house %>%
mutate(villa = case_when(
qm_total > 750 ~ "ja",
qm_total <= 750~ "nein"))
summarise
TIBBLE$VARIABLE
-Notation,
berechne den Mittelwert über alle Hauspreise mit
mean()
.mean(kc_house$preis)
[1] 540088
mean()
innerhalb der summarise()
Funktion.
Besteht ein Unterschied in den Resultaten dieser und der vorherigen
Aufgabe?kc_house %>%
summarise(
XX = mean(XX)
)
kc_house %>%
summarise(
preis_mean = mean(preis)
)
# A tibble: 1 × 1
preis_mean
<dbl>
1 540088.
max()
Funktion.kc_house %>%
summarise(
preis_max = max(preis)
)
# A tibble: 1 × 1
preis_max
<dbl>
1 7700000
arrange()
und der
desc()
Funktion den Datensatz nach preis
in
absteigender Reihenfolge und printe das Resultat. Richtig sortiert?kc_house <- kc_house %>%
arrange(desc(preis))
kc_house
# A tibble: 21,613 × 16
preis schlafzimmer badezimmer qf_wohnraum qf_parzelle stoecke ufer
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 7700000 6 8 12050 27600 2.5 0
2 7062500 5 4.5 10040 37325 2 1
3 6885000 6 7.75 9890 31374 2 0
4 5570000 5 5.75 9200 35069 2 0
5 5350000 5 5 8000 23985 2 0
6 5300000 6 6 7390 24829 2 1
7 5110800 5 5.25 8010 45517 2 1
8 4668000 5 6.75 9640 13068 1 1
9 4500000 5 5.5 6640 40014 2 1
10 4489000 4 3 6430 27517 2 0
# … with 21,603 more rows, and 9 more variables: qf_dachstock <dbl>,
# qf_keller <dbl>, baujahr <dbl>, postleitzahl <dbl>, qm_wohnraum <dbl>,
# qm_dachstock <dbl>, qm_keller <dbl>, qm_total <dbl>, villa <chr>
kc_house %>%
summarise(million_prozent = mean(XX > XX))
kc_house %>%
summarise(million_prozent = mean(preis > 1000000))
# A tibble: 1 × 1
million_prozent
<dbl>
1 0.0678
stoecke
) und
Badezimmer (badezimmer
) von Villen (villa
).
Verwende erst filter()
um Villen auszuwählen und danach
summarise()
.kc_house %>%
filter(villa == "ja") %>%
summarise(
stoecke_mean = mean(stoecke),
badezimmer_mean = mean(badezimmer)
)
# A tibble: 1 × 2
stoecke_mean badezimmer_mean
<dbl> <dbl>
1 1.92 3.68
group_by
und summarise
group_by()
, summarise()
und
n()
um zu berechnen wie viele Villen und wie viele normale
Häuser (nicht-Villen) im Datensatz vorhanden sind.kc_house %>%
group_by(XX) %>%
summarise(N = XX)
kc_house %>%
group_by(villa) %>%
summarise(N = n())
# A tibble: 2 × 2
villa N
<chr> <int>
1 ja 751
2 nein 20862
summarise()
, der den
mittlere Verkaufspreis von Villen und normalen Häusern (nicht-Villen)
berechnet?kc_house %>%
group_by(villa) %>%
summarise(N = n(),
preis_mean = mean(preis))
# A tibble: 2 × 3
villa N preis_mean
<chr> <int> <dbl>
1 ja 751 1541915.
2 nein 20862 504024.
min()
) und Maximum
(min()
).kc_house %>%
group_by(villa) %>%
summarise(N = n(),
preis_min = min(preis),
preis_mean = mean(preis),
preis_max = max(preis))
# A tibble: 2 × 5
villa N preis_min preis_mean preis_max
<chr> <int> <dbl> <dbl> <dbl>
1 ja 751 404000 1541915. 7700000
2 nein 20862 75000 504024. 3100000
baujahr
und berechne dann die mittlere Wohnfläche
(qm_wohnraum
).kc_house %>%
group_by(baujahr) %>%
summarise(N = n(),
wohnraum = mean(qm_wohnraum))
# A tibble: 116 × 3
baujahr N wohnraum
<dbl> <int> <dbl>
1 1900 87 161.
2 1901 29 164.
3 1902 27 179.
4 1903 46 140.
5 1904 45 149.
6 1905 74 183.
7 1906 92 168.
8 1907 65 177.
9 1908 86 158.
10 1909 94 177.
# … with 106 more rows
postleitzahl
)
98001, 98109, 98117 und 98199. Stelle ihm einen neuen Datensatz
theodorus
zusammen, welcher nur die Häuser dieser Gegend
enthält. Tipp: der %in%
Operator testet ob Elemente des
Vektors auf der rechten Seite im Vektor auf der linken Seite enthalten
sind.theodorus <- kc_house %>%
filter(XX %in% c(XX, XX, XX, XX))
theodorus <- kc_house %>%
filter(postleitzahl %in% c(98001, 98109, 98117, 98199))
theodorus %>%
group_by(postleitzahl, villa) %>%
summarise(preis_mean = mean(preis),
stoecke_min = min(stoecke),
stoecke_max = max(stoecke),
N = n())
# A tibble: 8 × 6
# Groups: postleitzahl [4]
postleitzahl villa preis_mean stoecke_min stoecke_max N
<dbl> <chr> <dbl> <dbl> <dbl> <int>
1 98001 ja 665667. 1 2 3
2 98001 nein 277589. 1 2.5 359
3 98109 ja 2508333. 2 2.5 3
4 98109 nein 833528. 1 3 106
5 98117 ja 898750 2 2.5 2
6 98117 nein 575626. 1 3 551
7 98199 ja 1762618. 1 3 12
8 98199 nein 753625. 1 3 305
ufer
)? Printe nur diese Zeile des
Datensatzes.kc_house %>%
group_by(postleitzahl) %>%
summarise(ufer_p = mean(ufer)) %>%
arrange(desc(ufer_p)) %>%
slice(1)
# A tibble: 1 × 2
postleitzahl ufer_p
<dbl> <dbl>
1 98070 0.203
kc_house %>%
mutate(preis_zu_flaeche = preis / qm_wohnraum) %>%
arrange(desc(preis_zu_flaeche)) %>%
slice(1)
# A tibble: 1 × 17
preis schlafzimmer badezimmer qf_wohnraum qf_parzelle stoecke ufer
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 874950 2 1 1080 4000 1 0
# … with 10 more variables: qf_dachstock <dbl>, qf_keller <dbl>, baujahr <dbl>,
# postleitzahl <dbl>, qm_wohnraum <dbl>, qm_dachstock <dbl>, qm_keller <dbl>,
# qm_total <dbl>, villa <chr>, preis_zu_flaeche <dbl>
kc_house %>%
group_by(postleitzahl) %>%
summarise(preis_mean = mean(preis)) %>%
arrange(desc(preis_mean)) %>%
slice(1:10)
# A tibble: 10 × 2
postleitzahl preis_mean
<dbl> <dbl>
1 98039 2160607.
2 98004 1355927.
3 98040 1194230.
4 98112 1095499.
5 98102 901258.
6 98109 879624.
7 98105 862825.
8 98006 859685.
9 98119 849448.
10 98005 810165.
baujahr | N | preis_mean | preis_max | qm_wohnraum_mean |
---|---|---|---|---|
1990 | 320 | 563966 | 3640900 | 234 |
1991 | 224 | 630441 | 5300000 | 244 |
1992 | 198 | 548169 | 2480000 | 223 |
1993 | 202 | 556612 | 3120000 | 226 |
1994 | 249 | 486834 | 2880500 | 209 |
1995 | 169 | 577771 | 3200000 | 224 |
1996 | 195 | 639534 | 3100000 | 240 |
1997 | 177 | 606058 | 3800000 | 234 |
1998 | 239 | 594159 | 1960000 | 241 |
kc_house %>%
filter(baujahr >= 1990 & baujahr < 1999) %>%
group_by(baujahr) %>%
summarise(N = n(),
preis_mean = mean(preis),
preis_max = max(preis),
qm_wohnraum_mean = mean(qm_wohnraum)) %>%
knitr::kable(digits = 0)
baujahr | N | preis_mean | preis_max | qm_wohnraum_mean |
---|---|---|---|---|
1990 | 320 | 563966 | 3640900 | 234 |
1991 | 224 | 630441 | 5300000 | 244 |
1992 | 198 | 548169 | 2480000 | 223 |
1993 | 202 | 556612 | 3120000 | 226 |
1994 | 249 | 486834 | 2880500 | 209 |
1995 | 169 | 577771 | 3200000 | 224 |
1996 | 195 | 639534 | 3100000 | 240 |
1997 | 177 | 606058 | 3800000 | 234 |
1998 | 239 | 594159 | 1960000 | 241 |
# Wrangling II mit dplyr and tidyr ---------------------------
library(tidyverse) # Lade tidyverse für dplyr
# Lese den basel Datensatz ein
basel <- read_csv("1_Data/basel.txt")
# Keine Gruppierungsvariable
bas <- basel %>%
summarise(
alter_m = mean(alter, na.rm = TRUE),
einkommen_median = median(einkommen, na.rm = TRUE),
N = n()
)
bas
# Eine Gruppierungsvariable
bas_ges <- basel %>%
group_by(geschlecht) %>%
summarise(
alter_m = mean(alter, na.rm = TRUE),
einkommen_median = median(einkommen, na.rm = TRUE),
N = n()
)
bas_ges
# Zwei Gruppierungsvariablen
bas_ges_bil <- basel %>%
group_by(geschlecht, bildung) %>%
summarise(
alter_m = mean(alter, na.rm = TRUE),
einkommen_median = median(einkommen, na.rm = TRUE),
N = n()
)
bas_ges_bil
# Gruppiere nach Geschlecht und Bildung und berechne den Mittelwert aller
# Variablen des Typs numeric
basel %>%
group_by(geschlecht, bildung) %>%
summarise_if(is.numeric, mean, na.rm = TRUE)
File | Zeilen | Spalten | Beschreibung |
---|---|---|---|
kc_house.csv | 21613 | 11 | Verkaufspreise von Häusern in King County zwischen Mai 2014 und Mai 2015. |
bevoelkerung.csv | 161 | 10 | Einwohnerzahlen Schweizer Städte von 1930 bis 2011. |
Erste 5 Zeilen und 5 Spalten von kc_house.csv
preis | schlafzimmer | badezimmer | qf_wohnraum | qf_parzelle |
---|---|---|---|---|
7700000 | 6 | 8.00 | 12050 | 27600 |
7062500 | 5 | 4.50 | 10040 | 37325 |
6885000 | 6 | 7.75 | 9890 | 31374 |
5570000 | 5 | 5.75 | 9200 | 35069 |
5350000 | 5 | 5.00 | 8000 | 23985 |
Variable | Beschreibung |
---|---|
preis | Preis in USD |
schlafzimmer | Anzahl Schlafzimmer |
badezimmer | Anzahl Badezimmer |
qf_wohnraum | Wohnraumfläche in Quadratfuss |
qf_parzelle | Parzellengrösse in Quadratfuss |
stoecke | Anzahl Stöcke |
ufer | Ist das Haus am Ufer gebaut (1) oder nicht (0) |
qf_dachstock | Dachstockfläche in Quadratfuss |
qf_keller | Kellerfläche in Quadratfuss |
baujahr | Baujahr |
postleitzahl | Postleitzahl |
Erste 5 Zeilen und 5 Spalten von bevoelkerung.csv
Stadtname | st_wbev_2011 | st_wbev_2001 | proz_ver-2001–2011 | bevdichte |
---|---|---|---|---|
Basel | 164516 | 164665 | -0.1 | 69 |
Bern | 125681 | 122211 | 2.8 | 24 |
Genève | 188234 | 175697 | 7.1 | 119 |
Lausanne | 129383 | 115272 | 12.2 | 31 |
Winterthur | 103075 | 89484 | 15.2 | 15 |
Variable | Beschreibung |
---|---|
Stadtname | Name der Stadt |
st_wbev_2011 | Wohnbevölkerung im Jahr 2011 |
st_wbev_2001 | Wohnbevölkerung im Jahr 2001 |
proz_ver-2001–2011 | Veränderung der Einwohnerzahl in Prozent zwischen 2001 und 2011 |
bevdichte | Bevölkerungsdichte |
st_wbev_1930 | Wohnbevölkerung im Jahr 1930 |
st_wbev_1970 | Wohnbevölkerung im Jahr 1970 |
st_wbev_1980 | Wohnbevölkerung im Jahr 1980 |
st_wbev_1990 | Wohnbevölkerung im Jahr 1990 |
st_wbev_2000 | Wohnbevölkerung im Jahr 2000 |
Paket | Installation | Beschreibung |
---|---|---|
tidyverse |
install.packages("tidyverse") |
Ein Metapaket für Data Science, einschliesslich
dplyr , ggplot2 und weitere Pakete |
Wrangling
Funktion | Paket | Beschreibung |
---|---|---|
rename() |
dplyr |
Umbenennen von Spalten |
select() |
dplyr |
Auswahl von Spalten basierend auf Name oder Index |
filter() |
dplyr |
Auswahl von Zeilen basieren auf einem logischen Ausdruck |
arrange() |
dplyr |
Sortiere Zeilen |
mutate() |
dplyr |
Hinzufügen von Spalten |
case_when() |
dplyr |
Recodieren von Spalten |
group_by(), summarise() |
dplyr |
Gruppierung von Daten zur Berechnung deskriptiver Statistiken |
pivot_longer() |
tidyr |
Transormation vom Wide ins Long Format |
pivot_wider() |
tidyr |
Transormation vom Long ins Wide Format |