2016-03-14 15 views
5

Sto tentando di aggiungere nuove colonne a data.table, dove i valori nelle righe dipendono dalla relazione relativa dei valori nella riga. Per essere più precisi, se c'è un valore X in una riga, vorrei sapere quanti altri valori sono nella stessa colonna (e gruppo), che si trovano all'interno di X-30.Contare il numero di valori in una finestra di un data.table per gruppo

Cioè, dato questo:

DT<-data.table(
X = c(1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1), 
Y = c(100, 101, 133, 134, 150, 156, 190, 200, 201, 230, 233, 234), 
Z = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)) 

vorrei ottenere una nuova colonna, con valori:

N <- c(0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 2) 

Ho provato quanto segue, ma non ho ricevuto la risultati che potrei usare:

DT[,list(Y,num=cumsum(Y[-.I]>DT[.I,Y]-30),Z),by=.(X)] 

Qualche idea come fare questo? (?)

risposta

6

Questo è probabilmente può essere realizzato con un rotolamento aderire, ma qui è un foverlaps alternativa per ora

DT[, `:=`(indx = .I, Y2 = Y - 30L, N = 0L)] # Add row index and a -30 interval 
setkey(DT, X, Y2, Y) # Sort by X and the intervals (for fovelaps) 
res <- foverlaps(DT, DT)[Y2 > i.Y2, .N, keyby = indx] # Run foverlaps and check what can we catch 
setorder(DT, indx) # go back to the original order 
DT[res$indx, N := res$N][, c("indx", "Y2") := NULL] # update results and remove cols 
DT 
#  X Y Z N 
# 1: 1 100 1 0 
# 2: 2 101 2 0 
# 3: 2 133 3 0 
# 4: 1 134 4 0 
# 5: 1 150 5 1 
# 6: 2 156 6 1 
# 7: 1 190 7 0 
# 8: 2 200 8 0 
# 9: 2 201 9 1 
# 10: 1 230 10 0 
# 11: 1 233 11 1 
# 12: 1 234 12 2 

In alternativa, utilizzare l'opzione which=TRUE di foverlaps per rendere la sovrapposizione unire più piccola:

# as above 
DT[, `:=`(indx = .I, Y2 = Y - 30L, N = 0L)] 
setkey(DT, X, Y2, Y) 

# using which=TRUE: 
res <- foverlaps(DT, DT, which=TRUE)[xid > yid, .N, by=xid] 
DT[res$xid, N := res$N] 
setorder(DT, indx) 
DT[, c("Y2","indx") := NULL] 
4

Ecco un altro modo:

DT[order(Y), N := 0:(.N-1) - findInterval(Y - 30, Y), by = X] 

all.equal(DT$N,N) # TRUE 
Problemi correlati