2016-07-28 17 views
0

ich einen Datensatz mit dieser Struktur haben:Letzte Beobachtung vorwärts bedingte auf mehreren Säulen getragen

ID = c(1,1,1,1,2,2,2,3,3,3,3) 
L40 = c(1, NA, NA, NA, 1, NA, NA, NA, 1, NA, NA) 
K50 = c(NA, NA, NA, NA, NA, 1, NA, NA, NA, NA, 1) 
df = data.frame(ID, L40, K50) 

Wenn fehlende Werte in Spalten L40 und K50 auftreten, möchte ich in dieser Spalte die letzte nicht-fehlenden Wert auf neue Rechnung vorzutragen , abhängig davon, dass die ID der vorherigen ID entspricht und die Werte in L40 und K50 in der aktuellen Zeile leer sind. Ich habe den folgenden Code angewendet:

library(tidyr) 
df2 <- df %>% group_by(ID) %>% fill(L40:K50) 

Dies erreicht nicht, was ich suche. Ich möchte, dass der vorherige nicht fehlende Wert nur dann in die nächste Zeile übernommen wird, wenn die anderen Spalten (außer ID) in dieser Zeile leer sind. Das ist, was ich will:

ID = c(1,1,1,1,2,2,2,3,3,3,3) 
L40 = c(1, 1, 1, 1, 1, NA, NA, NA, 1, 1, NA) 
K50 = c(NA, NA, NA, NA, NA, 1, 1, NA, NA, NA, 1) 
df3 = data.frame(ID, L40, K50) 

Antwort

0

Wir na.locf

library(data.table) 
library(zoo) 
setDT(df)[, if(any(is.na(K50[-1]))) lapply(.SD, na.locf) else .SD , by = ID] 
# ID L40 K50 
#1: 1 1 NA 
#2: 1 1 NA 
#3: 1 1 NA 
#4: 1 1 NA 
#5: 2 1 NA 
#6: 2 NA 1 
#7: 3 NA 1 
#8: 3 NA 1 
#9: 3 NA 1 

verwenden Eine Option dplyr verwenden wäre

library(dplyr) 
df %>% 
    mutate(ind = rowSums(is.na(.))) %>% 
    group_by(ID) %>% 
    mutate_each(funs(if(any(ind>1)) na.locf(., na.rm=FALSE) else .), L40:K50) %>% 
    select(-ind) 
#  ID L40 K50 
# <dbl> <dbl> <dbl> 
#1  1  1 NA 
#2  1  1 NA 
#3  1  1 NA 
#4  1  1 NA 
#5  2  1 NA 
#6  2 NA  1 
#7  3 NA  1 
#8  3 NA  1 
#9  3 NA  1 
+0

Nein, das erzeugt genau das gleiche Ergebnis, das ich vermeiden möchte. Ich möchte nicht, dass der Wert von L40 in der 5. Reihe in die 6. Reihe übertragen wird. – udden2903

+0

@ udden2903 Wie unterscheidet sich ID 2 von ID 3? – akrun

+0

ID 2 wie in ID = 2. Entschuldigung für die Verwirrung. – udden2903

0

ich mit dieser Frage für eine Weile herumgespielt, und mit meinen begrenzten Kenntnissen von RI kam das folgende Workaround. Ich habe eine Datumsspalte auf den ursprünglichen Datenrahmen zum Zweck der Erläuterung hinzugefügt:

ID = c(1,1,1,1,2,2,2,3,3,3,3) 
date = c(1,2,3,4,1,2,3,1,2,3,4) 
L40 = c(1, 1, NA, NA, 1, NA, NA, NA, 1, NA, NA) 
K50 = c(NA, 1, 1, NA, NA, 1, NA, NA, NA, NA, 1) 
df = data.frame(ID, date, L40, K50) 

Hier ist, was ich getan habe:

#gather the diagnosis columns in rows and keep only those rows where the patient has the associated diagnosis. 
df1 <- df %>% gather(diagnos, dummy, L40:K50) %>% filter(dummy==1) %>% arrange(ID, date) 

#concatenate across rows by ID and date to collect all diagnoses of an ID at a particular date. 
df2 <- df1 %>% group_by(ID, date) %>% mutate(diag = paste(diagnos, collapse=" ")) %>% select(-diagnos, -dummy) 

#convert into data tables in preparation for join 
Dt1 <- data.table(df) 
Dt2 <- data.table(df2) 

setkey(Dt1, ID, date) 
setkey(Dt2, ID, date) 

#Each observation in Dt1 is matched with the observation in Dt1 with the same date or, if that particular date is not present, 
#by the nearest previous date: 
final <- Dt2[Dt1, roll=TRUE] %>% distinct() 

Dies führt sie den Namen (s) der Diagnose bis zum nächsten beobachtete Diagnose.