Denken Sie bei allen Aufgaben daran, den Code im R-Skript sinnvoll zu gliedern und zu kommentieren.
Teil 1
Falls Sie am Workshop teilnehmen, laden Sie, falls noch nicht geschehen, zunächst den Datensatz über die eben vorgestellten Befehle in Ihr Environment. Außerdem sind die nachfolgenden Befehle aus dem Tutorial noch wichtig, die Sie also durchführen sollten, wenn es noch nicht geschehen ist!
# Pakete laden
library(readxl)
library(dplyr)
library(forcats)
# Pfad setzen
rstudioapi::getActiveDocumentContext()$path |>
dirname() |>
setwd()
# Daten einladen
data <- read_excel("Pennington_2021.xlsx", sheet = "Study 1 Year 7 Data")
# Faktoren anlegen
data$Gender <- factor(data$Gender,
levels = c(1, 2),
labels = c("weiblich", "männlich"))
data$Year <- as.factor(data$Year)
data$Year <- fct_recode(data$Year,
"7. Schuljahr" = "Year7",
"8. Schuljahr" = "Year8")
# fehlende Werte ersetzen
data$Total_Competence_Maths <- data$Total_Competence_Maths %>%
na_if(-9)
Falls Sie sich die Aufgaben unabhängig vom Workshop anschauen, werden folgende Schritte noch benötigt, die im Tutorial durchgeführt wurden.
# Pakete laden
library(readxl)
## Warning: Paket 'readxl' wurde unter R Version 4.3.2 erstellt
library(dplyr)
##
## Attache Paket: 'dplyr'
## Das folgende Objekt ist maskiert 'package:car':
##
## recode
## Die folgenden Objekte sind maskiert von 'package:stats':
##
## filter, lag
## Die folgenden Objekte sind maskiert von 'package:base':
##
## intersect, setdiff, setequal, union
library(forcats)
## Warning: Paket 'forcats' wurde unter R Version 4.3.1 erstellt
# Datensatz aus dem OSF einladen
source("https://pandar.netlify.app/workshops/fdz/fdz_data_prep.R")
## Lade nötiges Paket: httr
## Warning: Paket 'httr' wurde unter R Version 4.3.1 erstellt
# Faktoren anlegen
data$Gender <- factor(data$Gender,
levels = c(1, 2),
labels = c("weiblich", "männlich"))
data$Year <- as.factor(data$Year)
data$Year <- fct_recode(data$Year,
"7. Schuljahr" = "Year7",
"8. Schuljahr" = "Year8")
# fehlende Werte ersetzen
data$Total_Competence_Maths <- data$Total_Competence_Maths %>%
na_if(-9)
- Welchen Wert hat die 5. Person im Datensatz in der Variable
Total_Competence_English
? Lösen Sie die Aufgabe unter Verwendung der eckigen Klammern.
Lösung
Im Gegensatz zu dem Vorgehen im Tutorial wählen wir hier sowohl eine spezifische Zeile als auch eine spezifische Spalte aus. Wir müssen also vor und hinter dem Komma die entsprechenden Indizes angeben. Für die Spalte verwenden wir den Variablennamen, da es schneller ist, als die Spalte herauszufinden.#### Aufgaben des Tutorials zu Paketen und Deskriptivstatistiken ----
##### Teil 1 -----
###### Aufgabe 1 ------
data[5, "Total_Competence_English"] # Wert der 5. Person in der Variable Total_Competence_English
## # A tibble: 1 × 1
## Total_Competence_English
## <dbl>
## 1 3
- Betrachten Sie den aktuellen Typ der Variable
Ethnicity
. Verwandeln Sie diesen über eine passende Funktion in einen Faktor. Was ist der Modalwert der Variable?
Lösung
Zunächst schauen wir uns die Variable einmal an.
###### Aufgabe 2 ------
head(data$Ethnicity) # Inhalt der Variable
## [1] "White British" "White British" "White British" "White British" "White British"
## [6] "White British"
class(data$Ethnicity) # Typ der Variable
## [1] "character"
Wir wissen nun, dass die Variable als character
vorliegt. Um sie in einen Faktor umzuwandeln, nutzen wir die Funktion factor()
.
data$Ethnicity <- factor(data$Ethnicity) # Umwandlung in Faktor
Nun können wir den Modalwert der Variable bestimmen. Dieser ist die Kategorie mit der häufigsten Ausprägung. Hierfür nutzen wir die Funktion table()
.
table(data$Ethnicity) # Häufigkeiten der Kategorien
##
## Any other Asian background Any other white background Chinese
## 1 1 1
## Pakistani White and Asian White and Black African
## 1 1 2
## White British
## 293
Wenn wir jetzt nicht selbst nach der Kategorie suchen wollen, können wir die Funktion which.max()
nutzen, um den Index der häufigsten Kategorie zu finden.
table(data$Ethnicity) |> which.max() # Index der häufigsten Kategorie
## White British
## 7
Es handelt sich dabei um die Kategorie 7 - White British
.
- Überprüfen Sie die Variable
Total_Competence_English
auf fehlende Werte. Wie viele fehlende Werte sind in der Variable enthalten? Kodieren Sie diese korrekt und den Median (median()
) der Variable.
Lösung
Um die Variable auf fehlende Werte zu prüfen, können wir die Anzahl der fehlenden Werte mit der Kombination aus is.na()
und sum()
bestimmen.
###### Aufgabe 3 ------
is.na(data$Total_Competence_English) |> sum() # Anzahl der fehlenden Werte
## [1] 0
Aktuell liegen hier keine fehlenden Werte vor. Allerdings haben wir auch gesehen, dass die Werte eventuell noch “falsch” als -9 kodiert sind. Betrachten wir die absoluten Häufigkeiten.
table(data$Total_Competence_English) # Häufigkeiten der Werte
##
## -9 1 2 3 4 5
## 2 5 25 73 148 47
Hier fällt direkt wieder auf, dass -9 als Wert vorkommt. Wir können diesen Wert also ersetzen.
data$Total_Competence_English <- data$Total_Competence_English %>% na_if(-9) # Ersetzen der fehlenden Werte
Nun können wir den Median der Variable bestimmen. Wie beim Mittelwert muss hier das Argument na.rm = TRUE
gesetzt werden, um fehlende Werte zu ignorieren.
median(data$Total_Competence_English, na.rm = TRUE) # Median der Variable
## [1] 4
- Die Korrelation wird in R mit der Funktion
cor()
berechnet. Bestimmen Sie die Korrelation zwischen den VariablenTotal_Competence_Maths
undTotal_Competence_English
. Benutzen Sie die Hilfe für die Funktion, um das passende Argumente zum Umgang mit fehlenden Werte einzugeben.
Lösung
Zunächst einmal lässt sich hier festhalten, dass auch die Funktion cor()
auf fehlende Werte dahingehend reagiert, das Ergebnis auch als NA
auszugeben.
###### Aufgabe 4 ------
cor(data$Total_Competence_Maths, data$Total_Competence_English) # Korrelation zwischen den Variablen
## [1] NA
In der Hilfe stellen wir fest, dass es hier nicht das Argument na.rm
gibt, wie wir es von anderen Funktionen kennen. Wir können die Behandlung fehlender Werte jedoch über das Argument use
beeinflussen. Dabei gibt es Unterschiede zwischen dem paarweisen und listenweisen Löschen von fehlenden Werten - aber bei einer Korrelation zwischen zwei Variablen macht das nichts aus.
cor(data$Total_Competence_Maths, data$Total_Competence_English, use = "pairwise.complete.obs") # Korrelation zwischen den Variablen
## [1] 0.2179307
- Wie bereits geschildert führen die Autor:innen die Analyse des Datensatzes getrennt für die beiden Jahrgänge durch. Finden Sie heraus, wie man mit dem
dplyr
-Paket die Daten nach dem MerkmalYear
filtern und einen Subdatensatz erstellen könnte, in dem nur der jüngere Jahrgang enthalten ist. Bestimmen Sie den Mittelwert der VariableTotal_Competence_Maths
in diesem Subdatensatz.
Lösung
In dplyr
können wir die Funktion filter()
nutzen, um die Daten nach bestimmten Kriterien zu filtern. Hier wollen wir die Daten nach dem Merkmal Year
filtern. Die Anwendung benötigt die Angabe des Datensatzes und der Bedingung, die erfüllt sein muss.
###### Aufgabe 5 ------
filter(data, Year == "7. Schuljahr") # Filtern der Daten nach dem Merkmal Year
## # A tibble: 187 × 25
## Year Gender Ethnicity Total_Mindset Total_Competence_Maths Total_Competence_Eng…¹
## <fct> <fct> <fct> <dbl> <dbl> <dbl>
## 1 7. Sc… weibl… White Br… 36 4 3
## 2 7. Sc… weibl… White Br… 34 2 4
## 3 7. Sc… weibl… White Br… 28 4 4
## 4 7. Sc… weibl… White Br… 38 4 4
## 5 7. Sc… weibl… White Br… 26 3 3
## 6 7. Sc… weibl… White Br… 29 4 4
## 7 7. Sc… weibl… White Br… 32 3 4
## 8 7. Sc… weibl… White Br… 31 4 3
## 9 7. Sc… weibl… White Br… 28 3 5
## 10 7. Sc… weibl… White Br… 30 5 4
## # ℹ 177 more rows
## # ℹ abbreviated name: ¹Total_Competence_English
## # ℹ 19 more variables: Total_Competence_Science <dbl>, Total_SelfEsteem <dbl>,
## # Total_SocialSelfEsteem <dbl>, Total_AcademicSelfEfficacy <dbl>,
## # Total_SelfConcept_Maths <dbl>, Total_SelfConcept_English <dbl>,
## # Total_SelfConcept_Science <dbl>, SubjectSTEndorsement_Maths <dbl>,
## # SubjectSTEndorsement_English <dbl>, SubjectSTEndorsement_Science <dbl>, …
Damit ein Subdatensatz auch wirklich im Environment erscheint, müssen wir das Ergebnis der Funktion filter()
einer neuen Variable zuweisen.
data_year7 <- filter(data, Year == "7. Schuljahr") # Filtern der Daten nach dem Merkmal Year
Mit diesem Subdatensatz können wir nun ganz normal arbeiten - bspw. den Mittelwert der Variable Total_Competence_Maths
bestimmen.
mean(data_year7$Total_Competence_Maths, na.rm = TRUE) # Mittelwert der Variable Total_Competence_Maths
## [1] 3.784946
Teil 2
Falls Sie am Workshop teilnehmen, laden Sie, falls noch nicht geschehen, zunächst den Datensatz über die eben vorgestellten Befehle in Ihr Environment. Außerdem sind die nachfolgenden Befehle aus dem Tutorial / den Aufgaben noch wichtig, die Sie also durchführen sollten, wenn es noch nicht geschehen ist!
# Pakete laden
library(readxl)
library(dplyr)
library(forcats)
# Pfad setzen
rstudioapi::getActiveDocumentContext()$path |>
dirname() |>
setwd()
# Daten einladen
data <- read_excel("Pennington_2021.xlsx", sheet = "Study 1 Year 7 Data")
# Faktoren anlegen
data$Gender <- factor(data$Gender,
levels = c(1, 2),
labels = c("weiblich", "männlich"))
data$Year <- as.factor(data$Year)
data$Year <- fct_recode(data$Year,
"7. Schuljahr" = "Year7",
"8. Schuljahr" = "Year8")
data$Ethnicity <- as.factor(data$Ethnicity)
# Fehlende Werte ersetzen
data <- data %>%
mutate(across(where(is.numeric), ~ na_if(.x, -9)))
# Skalenwerte berechnen
data <- data %>%
mutate(Total_Competence = rowMeans(data[,c("Total_Competence_Maths", "Total_Competence_English", "Total_Competence_Science")]))
# Gruppierungsvariable erstellen
data <- data %>%
mutate(Achiever = case_when(
Total_Competence_Maths >= 4 &
Total_Competence_English >= 4 &
Total_Competence_Science >= 4 ~ "High Achiever",
Total_Competence_Maths == 1 &
Total_Competence_English == 1 &
Total_Competence_Science == 1 ~ "Low Achiever",
TRUE ~ "Medium Achiever" # Alle anderen Fälle
))
Falls Sie sich die Aufgaben unabhängig vom Workshop anschauen, werden folgende Schritte noch benötigt, die im Tutorial (und Teil 1 der Aufgaben) durchgeführt wurden.
source("https://pandar.netlify.app/workshops/fdz/fdz_data_prep.R")
# Faktoren anlegen
data$Gender <- factor(data$Gender,
levels = c(1, 2),
labels = c("weiblich", "männlich"))
data$Year <- as.factor(data$Year)
data$Year <- fct_recode(data$Year,
"7. Schuljahr" = "Year7",
"8. Schuljahr" = "Year8")
data$Ethnicity <- as.factor(data$Ethnicity)
# Fehlende Werte ersetzen
data <- data %>%
mutate(across(where(is.numeric), ~ na_if(.x, -9)))
# Skalenwerte berechnen
data <- data %>%
mutate(Total_Competence = rowMeans(data[,c("Total_Competence_Maths", "Total_Competence_English", "Total_Competence_Science")]))
# Gruppierungsvariable erstellen
data <- data %>%
mutate(Achiever = case_when(
Total_Competence_Maths >= 4 &
Total_Competence_English >= 4 &
Total_Competence_Science >= 4 ~ "High Achiever",
Total_Competence_Maths == 1 &
Total_Competence_English == 1 &
Total_Competence_Science == 1 ~ "Low Achiever",
TRUE ~ "Medium Achiever" # Alle anderen Fälle
))
- Erstellen Sie einen Skalenscore
Total_SelfConcept
als Mittelwert aus den VariablenTotal_SelfConcept_Maths
,Total_SelfConcept_Science
undTotal_SelfConcept_English
. Berechnen Sie dann Mittelwert und Median der neuen Variable.
Lösung
Um den Skalenscore zu berechnen, können wir die Funktion rowMeans()
nutzen. Diese berechnet den Mittelwert über die Zeilen eines Datensatzes.
##### Teil 2 -----
###### Aufgabe 1 ------
data$Total_SelfConcept <- rowMeans(data[, c("Total_SelfConcept_Maths", "Total_SelfConcept_Science", "Total_SelfConcept_English")]) # Berechnung des Skalenscores
Nun können wir den Mittelwert und Median der neuen Variable bestimmen. Dabei müssen wir auch hier drauf achten, fehlende Werte zu ignorieren.
mean(data$Total_SelfConcept, na.rm = TRUE) # Mittelwert der Variable
## [1] 12.71795
median(data$Total_SelfConcept, na.rm = TRUE) # Median der Variable
## [1] 12.66667
- Finden Sie heraus, welche Person den höchsten Wert in der Variable
Total_SelfConcept
hat. Wie lautet der Wert?
Lösung
Um den höchsten Wert in einer Variable zu finden, können wir die Funktion max()
nutzen. Auch hier müssen wir wieder darauf achten, fehlende Werte zu ignorieren.
###### Aufgabe 2 ------
max(data$Total_SelfConcept, na.rm = TRUE) # Höchster Wert in der Variable
## [1] 18.33333
Wie finden wir nun heraus, welche Person diesen Wert hat? Dafür können wir die Funktion which.max()
nutzen, die uns den Index des höchsten Wertes zurückgibt.
which.max(data$Total_SelfConcept) # Index der Person mit dem höchsten Wert
## [1] 112
- Die Forscherinnen wollen überprüfen, ob Sie für alle Jugendlichen bereits eine Karriere-Empfehlung machen können. Dafür muss auf einer (oder mehrerer) der 4 Leistungsvariablen (alle haben als Teil des Namens
AttainmentData
) ein Wert von über 10 für ein Kind vorliegen. Erstellen Sie eine neue kategoriale Variable mit dem NamenCareer_Recommendation
, die die WerteEmpfohlen
undnicht_empfohlen
enthält. Bestimmen Sie dann den Anteil der Werte an Kindern, für die Empfehlungen gegeben werden kann.
Lösung
Hier muss also wie im Tutorial eine kategoriale Variable erstellt werden - aus vorliegenden numerischen Werten. Dafür können wir die Funktion mutate()
und case_when()
nutzen.
###### Aufgabe 3 ------
data <- data %>%
mutate(Career_Recommendation = case_when(
Maths_AttainmentData > 10 |
Science_AttainmentData > 10 |
Eng_AttainmentData > 10 |
Computing_AttainmentData > 10 ~ "Empfohlen",
TRUE ~ "Nicht empfohlen"
)) # Erstellen der neuen Variable
Nun können wir den Anteil der Werte bestimmen, für die Empfehlungen gegeben werden können. Wir haben bereits gelernt, dass die absolute Häufigkeit mit table()
bestimmt werden kann.
table(data$Career_Recommendation) # Absolute Häufigkeiten
##
## Empfohlen Nicht empfohlen
## 92 208
Den Anteil könnten wir jetzt natürlich berechnen, indem wir die absolute Häufigkeit durch die Gesamtanzahl der Werte teilen. Allerdings gibt es auch eine Funktion, die das direkt für uns erledigt. prop.table()
gibt uns den Anteil der Werte zurück, wenn es auf ein table()
-Objekt angewendet wird. Wir können das direkt in einem Schritt mit der Pipe |>
machen.
table(data$Career_Recommendation) |> prop.table() # Anteil der Werte
##
## Empfohlen Nicht empfohlen
## 0.3066667 0.6933333
Lösung
Zunächst einmal stellt sich die Frage, welche Variable das Mindset der Schülerinnen abbildet. Wenn wir dafür in das Codebook der Excel-Datei schauen oder auch in den Daten, sehen wir, dass es sich um die Variable Total_Mindset
handelt.
Das restliche Vorgehen ist eine Anpassung aus dem Tutorial. Allerdings können wir in summarise()
anstatt einer auch mehrere Funktionen gleichzeitig nutzen. Wenn wir den Ergebnissen jeweils noch einen sprechenden Namen geben, wird die Ausgabe übersichtlicher.
###### Aufgabe 4 ------
data %>%
group_by(Career_Recommendation) %>%
summarise(mean_mindset = mean(Total_Mindset, na.rm = TRUE), # Mittelwert des Mindsets
sd_mindset = sd(Total_Mindset, na.rm = TRUE)) # Standardabweichung des Mindsets
## # A tibble: 2 × 3
## Career_Recommendation mean_mindset sd_mindset
## <chr> <dbl> <dbl>
## 1 Empfohlen 32.5 4.13
## 2 Nicht empfohlen 31.2 4.48
- In Teil 1 Aufgabe 4 haben wir bereits die Korrelation zwischen den Variablen
Total_Competence_Maths
undTotal_Competence_English
bestimmt. Dabei haben wir gesehen, dass das Argumentuse
genutzt werden kann, um den Umgang mit fehlenden Werten für genau diese eine Berechnung zu steuern. In einigen Tutorials und auch in Code-Chunks, die von LLMs produziert werden, wird die Funktionna.omit()
zum Ausschluss fehlender Werte auf dem gesamten Datensatz propagiert. Reduzieren Sie mit der Funktion den Datensatz auf einen Subdatensatzdata_red
und bestimmen Sie die Korrelation zwischen den VariablenTotal_Competence_Maths
undTotal_Competence_English
in diesem Subdatensatz. Versuchen Sie herauszufinden, wodurch die Unterschiede in den Ergebnissen zustande kommen.
Lösung
Zur Erinnerung nochmal das Ergebnis der Korrelation zwischen den Variablen `Total_Competence_Maths` und `Total_Competence_English` aus Teil 1 Aufgabe 4.###### Aufgabe 5 ------
cor(data$Total_Competence_Maths, data$Total_Competence_English, use = "pairwise.complete.obs") # Korrelation zwischen den Variablen
## [1] 0.2179307
Nun können wir den Datensatz reduzieren. Dafür nutzen wir die Funktion na.omit()
. Diese entfernt alle Zeilen, in denen mindestens ein fehlender Wert vorkommt.
data_red <- na.omit(data) # Reduzieren des Datensatzes
Die Variablennamen sind in dem Datensatz weiterhin die gleichen. Eine Behandlung fehlender Werte müssen wir in der cor()
-Funktion nun nicht mehr angeben.
cor(data_red$Total_Competence_Maths, data_red$Total_Competence_English) # Korrelation zwischen den Variablen
## [1] 0.2047514
Die Erklärung für den Unterschied liegt in dem Effekt der na.omit()
-Funktion. Diese entfernt alle Zeilen, in denen mindestens ein fehlender Wert vorkommt. Dadurch werden auch Personen ausgeschlossen, die auf Variablen fehlende Werte haben, die für die Korrelation nicht relevant sind. Das kann zu Unterschieden in den Ergebnissen führen. Unabhängig davon, dass auch paarweise und listenweiser Fallausschluss problematische Aspekte haben, ist es wichtig, dass die Funktion na.omit()
nur in sehr spezifischen Fällen genutzt wird.