2014-05-10 13 views
5

Ich habe eine df wie folgt, die 20 Personen über 5 Haushalte hat. Einige Personen im Haushalt haben keine Daten darüber, ob sie eine med_card haben oder nicht. Ich möchte diesen Menschen den gleichen Wert geben wie die anderen Menschen in ihrem Haushalt (kein NA-Wert, ein echter Binärwert, der entweder 0 oder 1 ist).ersetzen NA-Wert mit dem Gruppenwert

Ich habe versucht den folgenden Code, der ein Schritt in die richtige Richtung ist denke ich - aber ist nicht 100% richtig, weil a) es nicht funktioniert, wenn der erste Wert für med_card pro Haushalt ist NA und b) es nicht NA im Haushalt für alle Menschen ersetzen 1.

DF<- ddply(df, .(hhold_no), function(df) {df$med_card[is.na(df$med_card)] <- head(df$med_card, na.rm=TRUE); return(df)}) 

alle Zeiger würde sehr geschätzt werden, Danke

Probe df

df 
    person_id hhold_no med_card 
1   1  1  1 
2   2  1  1 
3   3  1  NA 
4   4  1  NA 
5   5  1  NA 
6   6  2  0 
7   7  2  0 
8   8  2  0 
9   9  2  0 
10  10  3  NA 
11  11  3  NA 
12  12  3  NA 
13  13  3  1 
14  14  3  1 
15  15  4  1 
16  16  4  1 
17  17  5  1 
18  18  5  1 
19  19  5  NA 
20  20  5  NA 

und Code

person_id<-as.numeric(c(1:20)) 
hhold_no<-as.numeric(c(1,1,1,1,1,2,2,2,2,3,3,3,3,3,4,4,5,5,5,5)) 
med_card<-as.numeric(c(1,1,NA,NA,NA,0,0,0,0,NA,NA,NA,1,1,1,1,1,1,NA,NA)) 
df<-data.frame(person_id,hhold_no, med_card) 

Wunsch Ausgang

df 
    person_id hhold_no med_card med_card_new 
1   1  1  1   1 
2   2  1  1   1 
3   3  1  NA   1 
4   4  1  NA   1 
5   5  1  NA   1 
6   6  2  0   0 
7   7  2  0   0 
8   8  2  0   0 
9   9  2  0   0 
10  10  3  NA   1 
11  11  3  NA   1 
12  12  3  NA   1 
13  13  3  1   1 
14  14  3  1   1 
15  15  4  1   1 
16  16  4  1   1 
17  17  5  1   1 
18  18  5  1   1 
19  19  5  NA   1 
20  20  5  NA   1 

Antwort

6

ave Versuchen zu machen. Es wendet eine Funktion auf Gruppen an. Werfen Sie einen Blick auf ?ave für Details, zB:

df$med_card_new <- ave(df$med_card, df$hhold_no, FUN=function(x)unique(x[!is.na(x)])) 

# person_id hhold_no med_card med_card_new 
#1   1  1  1   1 
#2   2  1  1   1 
#3   3  1  NA   1 
#4   4  1  NA   1 
#5   5  1  NA   1 
#6   6  2  0   0 
#7   7  2  0   0 
#8   8  2  0   0 
#9   9  2  0   0 

Bitte beachten Sie, dass dies nur funktioniert, wenn nicht alle Werte in einem Haushalt NA sind und das soll nicht unterscheiden (zB Person 1 == 1, Person 2 == 0).

+0

danke! Ich hatte einige sehr ungeschickte Versuche mit Ave gemacht, aber konnte es nicht ganz für mich arbeiten. Danke noch einmal! :) – user2363642

5

das ist genau das, was na.aggregate (link) im Zoo Paket tut:

library(zoo) 

transform(df, med_card_new = na.aggregate(med_card, by = hhold_no)) 
+0

danke, hatte ich noch nie zuvor gesehen. sehr praktisch. :) – user2363642

+0

Habe das einfach wunderbar genutzt, aber NaNs für Fälle bekommen, die keine Daten hatten, die es zusammenfassen könnte. Hatte Probleme beim Umwandeln von NaN in NA und fand den besten Weg dazu "df [is.na (df)] <- NA". – seeellayewhy

2

data.table Lösung

library(data.table) 
setDT(df)[, med_card2 := unique(med_card[!is.na(med_card)]), by = hhold_no] 

#  person_id hhold_no med_card med_card2 
# 1:   1  1  1   1 
# 2:   2  1  1   1 
# 3:   3  1  NA   1 
# 4:   4  1  NA   1 
# 5:   5  1  NA   1 
# 6:   6  2  0   0 
# 7:   7  2  0   0 
# 8:   8  2  0   0 
# 9:   9  2  0   0 
# 10:  10  3  NA   1 
# 11:  11  3  NA   1 
# 12:  12  3  NA   1 
# 13:  13  3  1   1 
# 14:  14  3  1   1 
# 15:  15  4  1   1 
# 16:  16  4  1   1 
# 17:  17  5  1   1 
# 18:  18  5  1   1 
# 19:  19  5  NA   1 
# 20:  20  5  NA   1 
Verwandte Themen