2013-07-23 12 views
9

Ho un frame di dati con AN e voglio sostituire l'AN con la riga significaTrovare e sostituire i valori mancanti con la riga dire

c1 = c(1,2,3,NA) 
c2 = c(3,1,NA,3) 
c3 = c(2,1,3,1) 

df = data.frame(c1,c2,c3) 

> df 
    c1 c2 c3 
1 1 3 2 
2 2 1 1 
3 3 NA 3 
4 NA 3 1 

in modo che

> df 
    c1 c2 c3 
1 1 3 2 
2 2 1 1 
3 3 3 3 
4 2 3 1 

risposta

10

Molto simile a @ Baptiste risposta

> ind <- which(is.na(df), arr.ind=TRUE) 
> df[ind] <- rowMeans(df, na.rm = TRUE)[ind[,1]] 
+1

+1 buon uso dell'argomento' arr.ind' spesso trascurato –

+0

Ho trovato se ho righe intere di NA, si verifica un errore. È un'etichetta corretta porre questa come una domanda completamente nuova? – Brian

2

La mia soluzione è

rwmns = rowMeans(df,na.rm=TRUE) 
df$c1[is.na(df$c1)] = rwmns[is.na(df$c1)] 
df$c2[is.na(df$c2)] = rwmns[is.na(df$c2)] 
df$c3[is.na(df$c3)] = rwmns[is.na(df$c3)] 
> df 
    c1 c2 c3 
1 1 3 2 
2 2 1 1 
3 3 3 3 
4 2 3 1 

C'è un modo più elegante, soprattutto quando qualcuno ha molte colonne?

+4

Grande lavoro fino a venire con la propria soluzione. Puoi usare '[[' per indicizzare invece, in modo che ogni riga diventi 'df [[nome_colonna]] [is.na (df [[nome_col]]) <- rwmns [is.na (df [[nome_col]]) '. In questo modo, puoi eseguire il loop o utilizzare una famiglia apply sui nomi delle colonne su cui desideri eseguire la sostituzione. – Justin

4

Penso che questo funziona,

df[which(is.na(df), arr.ind=TRUE)] <- rowMeans(df[!complete.cases(df), ], na.rm=TRUE) 
+0

+1 bella soluzione !! Molto meglio del mio pigro 'apply'! –

+0

è un po 'ridondante usare sia is.na che complete.cases; probabilmente c'è un modo più efficace in due linee – baptiste

+1

. Forse questo? 'idx <- che (is.na (df), arr.ind = TRUE); df [idx] <- rowMeans (df [idx [, 1],], na.rm = TRUE) ' –

3

Utilizzando apply (notare l'oggetto restituito è un matrix):

t(apply(df , 1 , function(x) { x[ is.na(x) ] = mean(x , na.rm = TRUE); x })) 
    c1 c2 c3 
[1,] 1 3 2 
[2,] 2 1 1 
[3,] 3 3 3 
[4,] 2 3 1 

Usiamo qualsiasi funzione anonima per modificare i valori di ogni NA in ogni riga allo mean di quella riga. L'unico vantaggio è che non devi più digitare quando il numero di righe aumenta. Non è particolarmente efficiente o veloce in senso computazionale, ma più in senso cognitivo (non si noterà se non si hanno migliaia di righe).

2

Un'altra opzione è na.aggregate da library(zoo) dopo la trasposizione del dataset

library(zoo) 
df[] <- t(na.aggregate(t(df))) 
df 
# c1 c2 c3 
#1 1 3 2 
#2 2 1 1 
#3 3 3 3 
#4 2 3 1 
Problemi correlati