Seite 1 von 1

Last observation carried forward

Verfasst: Mo Jun 15, 2020 4:48 pm
von R_Student
Hi ihr Lieben,

Hier meine neuste Frage. Ich hoffe es ist ok, wenn ich so viel hier frage!

Ich bin gerade dabei meinen Ergebnis-Datensatz zu bearbeiten.
Dieser beeinhaltet die Variablen:
Person (CODE)(Format: Zeichenvektor), Messzeitpunkt (Format: Zeichenvektor; "POST","Z05" bis "Z95"), Datum des Messzeitpunktes (Format: Datum), Variable1

Ich habe also für jede Person (CODE) mehrere Zeilen mit Werten der Variable1 zu unterschiedlichen Messzeitpunkten. Mich interessiert jedoch nur der letzte Messzeitpunkt "POST" oder wenn dieser nicht vorhanden ist der letzte Werte (also der Wert mit dem Datum, welches am nächsten am jetzigen dran ist).
Ich möchte also einen neuen Datensatz in dem für jede Person (CODE) der letzte Wert von Variable1 steht sowie die Information welcher Messzeitpunkt ("POST" oder "Z05" oder etc.) verwendet wurde. Jede Zeile ist also genau eine Person. Ist dies machbar?

Ich hoffe jemand kann mir weiterhelfen.
LG
Lea

Re: Last observation carried forward

Verfasst: Mo Jun 15, 2020 5:54 pm
von bigben
...und auch hier wäre ein Beispiel in R Code angebracht. Links, wie man das macht, haben wir in einem anderen Thread schon gepostet.

Re: Last observation carried forward

Verfasst: Mo Jun 15, 2020 6:53 pm
von R_Student
Oh ja klar. Entschuldige!
Hier ein vereinfachter Datensatz:

Code: Alles auswählen

Outcome <- data.frame(CODE=c("AB1","AB1","CD2","CD2","EF3"), Messzeitpunkt=c("PO","Z05","Z10","Z05", "Z05"), Datum=c("2008-08-14","2008-02-14", "2015-09-11", "2015-07-03", "2019-09-25"), Variable1=c(1,3,2,1,3), stringsAsFactors = FALSE)
Gewünscht wäre ein Datensatz der dann am Ende in etwa so aussieht:

Code: Alles auswählen

Outcome_korrigiert <-data.frame(CODE=c("AB1","CD2","EF3"), Messzeitpunkt=c("PO","Z10", "Z05"), Variable1=c(1,2,3), stringsAsFactors = FALSE)
Also eine Person pro Zeile mit jeweils entweder dem Wert der Variable1 zum Zeitpunkt Post ("Po") oder wenn kein Post Wert vorhanden ist zum letzten Messzeitpunkt. Das Datum muss in diesem Datensatz nicht enthalten sein.

Ich hoffe das macht mein Problem etwas anschaulicher!

Re: Last observation carried forward

Verfasst: Mo Jun 15, 2020 10:21 pm
von bigben
Ist ein bisschen mit der heißen Nadel gestrickt und wahrscheinlich auch nicht das eleganteste, was R hergibt, aber für die Uhrzeit bin ich mir mit ganz zufrieden

Code: Alles auswählen

Outcome <- data.frame(CODE=c("AB1","AB1","CD2","CD2","EF3"), Messzeitpunkt=c("PO","Z05","Z10","Z05", "Z05"), Datum=c("2008-08-14","2008-02-14", "2015-09-11", "2015-07-03", "2019-09-25"), Variable1=c(1,3,2,1,3), stringsAsFactors = FALSE)
Outcome$Datum <- as.Date(Outcome$Datum)
 
letzte <- function(datfra){
  index <- which(datfra$Messzeitpunkt == "PO")
  if(length(index)>0) return(datfra[index[1],])
  index <-which.max(datfra$Datum)
  return(datfra[index,])
}

do.call(rbind, by(Outcome, Outcome$Variable, letzte))
Beachte
1. Zur Definition des Datensatzes gehört der as.Date Aufruf
2. viewtopic.php?f=20&t=29

LG,
Bernhard

Re: Last observation carried forward

Verfasst: Mi Jun 17, 2020 10:49 am
von R_Student
Lieber Bernhard,

vielen, vielen Dank für deine Mühe!!!
Ich habe versucht deine Syntax auf meinen Datnesatz anzuwenden und dann ist bei mir das Problem aufgefallen, dass ich viel zu wenig Personen habe (es scheinen also manche Personen zu verschwinden und einige erscheinen doppelt (das ist wahrscheinlich mein Fehler, da die Werte der Variable keine ganzen sondern Dezimalzahlen sind; hab das jetzt im Beispieldatensatz angepasst und komme dort zu einem ähnlichen Ergebnis/Problem):

Code: Alles auswählen

Outcome <- data.frame(CODE=c("AB1","AB1","CD2","CD2","EF3"),
                      Messzeitpunkt=c("PO","Z05","Z10","Z05", "Z05"), 
                      Datum=c("2008-08-14","2008-02-14", "2015-09-11",
                              "2015-07-03", "2019-09-25"), 
                      Variable1=c(1.4,3.5,1.3,0.4,3.5), stringsAsFactors = FALSE) #Die Variable1 hat eine Range von 0 - 4 (intervallskalliert)
Outcome$Datum <- as.Date(Outcome$Datum)

letzte <- function(datfra){
  index <- which(datfra$Messzeitpunkt == "PO")
  if(length(index)>0) return(datfra[index[1],])
  index <-which.max(datfra$Datum)
  return(datfra[index,])
}

Outcome_Personenebene <- do.call(rbind, by(Outcome, Outcome$Variable, letzte))



#Ergebnis:

       CODE      Messzeitpunkt      Datum            Variable1
0.4  CD2           Z05                   2015-07-03       0.4        
1.3  CD2           Z10                   2015-09-11       1.3            #hier die doppelte Nennung
1.4  AB1            PO                   2008-08-14       1.4
3.5  EF3           Z05                   2019-09-25       3.5
Ich hoffe jemand kann helfen!

Re: Last observation carried forward

Verfasst: Mi Jun 17, 2020 11:54 am
von jogo
Hallo Lea,

worin besteht die doppelte Nennung?
Für jeden Wert von Outcome$Variable ist genau eine Zeile im Ergebnis vorhanden.

Gruß, Jörg

Re: Last observation carried forward

Verfasst: Mi Jun 17, 2020 12:11 pm
von bigben
Ok, zurück zum Anfang. Vermutlich liegt es daran, dass Du eine Zeile pro Code haben möchtest, ich aber eine Zeile pro Variable1 berechnet habe. Dein Outcome_korrigiert vom reproduzierbaren Beispiel oben ist für beide Varianten identisch.
Also Variante 1: Versuch meinen Code zu verstehen und zu adaptieren. Wenn Du Fragen beim verstehen hast, helfen wir gerne.
Variante 2: mach nochmal ein reproduzierbares Beispiel mit Musterlösung, dass in dieser Hinsicht eindeutig ist.

LG,
Bernhard

Re: Last observation carried forward

Verfasst: Mi Jun 17, 2020 12:47 pm
von jogo
Hallo Lea,

wenn Du nach $CODE gruppieren möchtest, dann musst Du das in by() nur entsprechend angeben:

Code: Alles auswählen

do.call(rbind, by(Outcome, Outcome$CODE, letzte))

Code: Alles auswählen

> do.call(rbind, by(Outcome, Outcome$CODE, letzte))
    CODE Messzeitpunkt      Datum Variable1
AB1  AB1            PO 2008-08-14       1.4
CD2  CD2           Z10 2015-09-11       1.3
EF3  EF3           Z05 2019-09-25       3.5
Gruß, Jörg

Re: Last observation carried forward

Verfasst: Mi Jun 17, 2020 1:10 pm
von R_Student
Also Leute ihr seid genial!!! Es funktioniert mit der Modifikation von Jörg!
Ihr habt gerade 10.000 Karma-Punkte gesammelt!
Danke euch beiden!