Neue Spalte basierend auf Werten anderer Spalten

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

Antworten
kosa
Beiträge: 27
Registriert: Mo Sep 02, 2019 6:47 pm

Neue Spalte basierend auf Werten anderer Spalten

Beitrag von kosa »

Hallo Ihr Lieben,

ich habe einen Datensatz, bei dem jede Zeile einen Messzeitpunkt von einem Schüler darstellt. Befragt wurden Schüler verschiedener Kurse zu mehreren Messzeitpunkten. Der Datensatz befindet sich somit in einem long-Format. Ein Beispiel befindet sich unten. Man sieht, dass jeder Schüler, je nach Anzahl der Teilnahme am Fragebogen zu den verschiedenen Messzeitpunkten eine Zeile bekommt. Die Kurszugehörigkeiten ist in der Variable "Kurs_ID2" festgehalten. Die Variable "F1" steht für das Antwortverhalten eines Schülers zu einer Frage im Fragebogen.

Code: Alles auswählen

 Schüler_ID Zeitpunkt Kurs_ID2    F1
   <fct>      <fct>     <fct>    <dbl>
 1 01ELVN     1         H_GK3        3
 2 01ELVN     2         H_GK3        5
 3 01ESPI     1         K_GKb        3
 4 01ESPI     2         K_GKb        6
 5 01ESPI     3         K_Gkb       NA
 6 01FZWF     1         L_GK3        2
 7 01LEGN     1         L_GK2        4
 8 01LEGN     2         L_GK2        5
 9 01LEGN     3         L_GK2        5
10 01NAAD     1         H_GK2        4

Nun würde ich gern für jeden Kurs einen Mittelwert für F1 bilden, aber nur mit den Antworten zum ersten Messzeitpunkt und diesen Wert dann in einer neuen Variablen "F1_Kurs_mean" abspeichern. In jeder Zeile soll also der Kursmittelwert des zutreffenden Kurses stehen.

Ich stelle mir das Endergebnis so vor:

Code: Alles auswählen

Schüler_ID Zeitpunkt Kurs_ID2    F1 Wissen.Kurs.mean
   <fct>      <fct>     <fct>    <dbl>            <dbl>
 1 01ELVN     1         H_GK3        3             4   
 2 01ELVN     2         H_GK3        5            4   
 3 01ESPI     1         K_GKb        3             4.34
 4 01ESPI     2         K_GKb        6            4.34  
 5 01ESPI     3         K_Gkb       NA            4.34   
 6 01FZWF     1         L_GK3        2            2   
 7 01LEGN     1         L_GK2        4            4.27   
 8 01LEGN     2         L_GK2        5            4.27   
 9 01LEGN     3         L_GK2        5             4.27
10 01NAAD     1         H_GK2        4             4.16
Ich habe dabei an die ave-Funktion gedacht, allerdings weiß ich nicht, wie ich berücksichtigen soll, dass der Mittelwert nur aus den Werten zum ersten Messpunkt berechnet wird und die neue Spalte entsprechend der Mittelwerte aufgefüllt wird.

Ich habe es mit folgendem Befehl versucht:

Code: Alles auswählen

dat$Wissen.Kurs.mean <- ave(dat$F1, dat$Kurs_ID2[dat$Zeitpunkt == 1], FUN=function(x) mean(x))
Da bekomme ich aber folgendes:

Code: Alles auswählen

  Schüler_ID Zeitpunkt Kurs_ID2    F1 Wissen.Kurs.mean
   <fct>      <fct>     <fct>    <dbl>            <dbl>
 1 01ELVN     1         H_GK3        3             4   
 2 01ELVN     2         H_GK3        5            NA   
 3 01ESPI     1         K_GKb        3             4.34
 4 01ESPI     2         K_GKb        6            NA   
 5 01ESPI     3         K_Gkb       NA            NA   
 6 01FZWF     1         L_GK3        2            NA   
 7 01LEGN     1         L_GK2        4            NA   
 8 01LEGN     2         L_GK2        5            NA   
 9 01LEGN     3         L_GK2        5             4.27
10 01NAAD     1         H_GK2        4             4.16
Hier ein hoffentlich reproduzierbares Beispiel:

Code: Alles auswählen

Schüler_ID <- c("A","A","B","B","B","C","D","D","D","E")
Zeitpunkt <- c("1","2","1","2","3","1","1","2","3","1")
Kurs_ID2 <- c("H_GK3","H_GK3","K_GKb","K_GKb","K_GKb","L_GK3","L_GK2","L_GK2","L_GK2","H_GK2")
F1 <- c(3,5,3,6,NA,2,4,5,5,4)

dat <- data.frame(Schüler_ID,Zeitpunkt,Kurs_ID2,F1)
Ich danke euch bereits vielmals!
jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Neue Spalte basierend auf Werten anderer Spalten

Beitrag von jogo »

Hallo kosa,

die andere übliche Variante ist klassische Datenbankarbeit:
1. aggregiere über einer Teilmenge der Beobachtungen, um den Mittelwert je Kurs auszurechnen.
2. binde diese Ergebnisse per merge() wieder an die ursprünglichen Daten.

also so:

Code: Alles auswählen

dat <- data.frame(
  Schüler_ID =c("A","A","B","B","B","C","D","D","D","E"),
  Zeitpunkt =c("1","2","1","2","3","1","1","2","3","1"),
  Kurs_ID2 =c("H_GK3","H_GK3","K_GKb","K_GKb","K_GKb","L_GK3","L_GK2","L_GK2","L_GK2","H_GK2"),
  F1 =c(3,5,3,6,NA,2,4,5,5,4)
)

M <- aggregate(F1 ~ Kurs_ID2, data=dat, FUN=mean, subset=Zeitpunkt==1)
names(M)[2] <- "MittelF1"
merge(dat, M, all.x=TRUE)
Die data.table-Variante kann so aussehen:

Code: Alles auswählen

library("data.table") 
setDT(dat)
dat[dat[Zeitpunkt==1, mean(F1), Kurs_ID2], on="Kurs_ID2"]
Gruß, Jörg
Antworten