2012-03-01 14 views
12

Ogni settimana un set di dati incompleto per un'analisi. Sembra:Aggiungere il valore mancante nella colonna con il valore della riga sopra

df1 <- data.frame(var1 = c("a","","","b",""), 
      var2 = c("x","y","z","x","z")) 

Mancano alcuni valori var1. Il set di dati dovrebbe apparire così:

df2 <- data.frame(var1 = c("a","a","a","b","b"), 
      var2 = c("x","y","z","x","z")) 

Attualmente utilizzo una macro di Excel per fare ciò. Ma questo rende più difficile automatizzare l'analisi. D'ora in poi mi piacerebbe farlo in R. Ma non ho idea di come farlo.

Grazie per il vostro aiuto.

DOMANDA AGGIORNAMENTO DOPO COMMENTO

var2 non è rilevante per la mia domanda. L'unica cosa che sto cercando è. Ottieni da df1 a df2.

df1 <- data.frame(var1 = c("a","","","b","")) 
df2 <- data.frame(var1 = c("a","a","a","b","b")) 
+0

che non capisco il modello che si sta utilizzando per sostituire i valori mancanti con. Sostituire il primo set di spazi vuoti con 'a' fino a 'b', quindi sostituire gli spazi vuoti con 'b' fino a 'c' e così via ... – John

+0

Ci scusiamo per la confusione. var2 non è affatto pertinente per la domanda. Aggiornerò la mia domanda – jeroen81

+2

Si aggiunge il pacchetto tidyr v0.3.0 'fill()'. Questa è esattamente la cosa che volevo. – jeroen81

risposta

16

Qui è un modo di farlo facendo uso di codifica run-length (rle) e la sua inversa rle.inverse:

fillTheBlanks <- function(x, missing=""){ 
    rle <- rle(as.character(x)) 
    empty <- which(rle$value==missing) 
    rle$values[empty] <- rle$value[empty-1] 
    inverse.rle(rle) 
} 

df1$var1 <- fillTheBlanks(df1$var1) 

I risultati:

df1 

    var1 var2 
1 a x 
2 a y 
3 a z 
4 b x 
5 b z 
+0

Grazie, questa è la risposta che stavo cercando. – jeroen81

+0

Molto utile, grazie Andrie! Ho adattato questo alle mie esigenze e prodotto un mostro (possibilmente pericoloso), ma per la cronaca: https://pastebin.com/82kvNp1D – PatrickT

10

Qui è un modo più semplice:

library(zoo) 
df1$var1[df1$var1 == ""] <- NA 
df1$var1 <- na.locf(df1$var1) 
+0

+1 Must. Ottenere. Familiare. Con. Zoo. – Andrie

2

Ecco un altro modo, che è leggermente più corta e non costringere a carattere:

Fill <- function(x,missing="") 
{ 
    Log <- x != missing 
    y <- x[Log] 
    y[cumsum(Log)] 
} 

Risultati:

# For factor: 
Fill(df1$var1) 
[1] a a a b b 
Levels: a b 

# For character: 
Fill(as.character(df1$var1)) 
[1] "a" "a" "a" "b" "b" 
+0

+1 Bello .... – Andrie

Problemi correlati