2015-08-17 16 views
7

Ho un data.table con un gran numero di valori mancanti. Vorrei riempirli aggiungendo o sottraendo valori dai valori disponibili in data.table. In particolare, in considerazione questi dati:Riempimento in valori NA in base ad altri valori nella colonna

> test = data.table(id=c("A","A","A","A","A","B","B","B","B","B"), x=c(NA,NA,0,NA,NA,NA,NA,0,NA,NA)) 
> test 
    id x 
1: A NA 
2: A NA 
3: A 0 
4: A NA 
5: A NA 
6: B NA 
7: B NA 
8: B 0 
9: B NA 
10: B NA 

devo un'operazione che trasforma questa in cui:

id x 
1: A -2 
2: A -1 
3: A 0 
4: A 1 
5: A 2 
6: B -2 
7: B -1 
8: B 0 
9: B 1 
10: B 2 

Fondamentalmente una versione di na.locf che incrementa l'ultimo valore piuttosto che ripeterlo.

risposta

8

Possiamo raggruppare per 'id' e prendere la differenza del numero di riga (seq_len(.N)) con la posizione (which) in 'x' dove è 0 (!x). Sto eseguendo il wrapping con as.numeric poiché la colonna "x" è numeric nel set di dati di input, ma dalla differenza, viene convertita in "intero". Se c'è uno scontro nel class durante l'assegnazione (:=), data.table mostrerà un errore in quanto deve corrispondere allo class.

test[, x:= as.numeric(seq_len(.N)-which(!x)), id] 
test 
# id x 
# 1: A -2 
# 2: A -1 
# 3: A 0 
# 4: A 1 
# 5: A 2 
# 6: B -2 
# 7: B -1 
# 8: B 0 
# 9: B 1 
#10: B 2 

!x altrimenti è scritto in modo più chiaro come x==0. Restituisce un vettore logico di TRUE/FALSE. Se ci sono valori NA, rimarrà come NA. Con il wrapping con which, otteniamo la posizione del valore 0. Nell'esempio, è 3 per ciascun 'id'.

+1

Funziona come un fascino! Grazie mille, ho provato ogni sorta di combinazioni di locf e cumsum. – phildeutsch

+0

@phildeutsch Grazie per il feedback. Felice di sapere che funziona. – akrun

+0

@akrun Mi piacerebbe sapere perché 'which (! X)' restituisce 3? – jazzurro