2016-03-18 10 views
5

Diciamo che ho il seguente tabella di dati:Come posso rimodellare un data.table quando l'ordine dei registri determina la categoria?

dt=data.table(type=c('big','medium','small','small' 
        ,'medium','small','small' 
        ,'big','medium','small','small') 
      ,category=letters[1:11]) 

     type category 
1: big  a 
2: medium  b 
3: small  c 
4: small  d 
5: medium  e 
6: small  f 
7: small  g 
8: big  h 
9: medium  i 
10: small  j 
11: small  k 

In questo caso ho una gerarchia di categorie: il tipo di 'grande' è lo stesso per tutte le righe fino a quando si vede un tipo seguente 'grande'. E il comportamento è lo stesso per ogni tipo.

Il Reshape che voglio mi deve comprendere i seguenti:

dt=data.table(type=c('big','medium','small','small' 
        ,'medium','small','small' 
        ,'big','medium','small','small') 
       ,category=letters[1:11]) 


    big medium small 
1: a  b  c 
2: a  b  d 
3: a  e  f 
4: a  e  g 
5: h  i  j 
6: h  i  k 

Come si può vedere ogni categoria solo le modifiche quando viene trovato un registro della stessa categoria, l'ordine è importante impostare questa categorie.

Pensi che ci sia un modo per farlo senza usare un?

risposta

8

Ecco un approccio che è possibile utilizzare. Avrete bisogno na.locf da "zoo":

library(data.table) 
library(zoo) 

In primo luogo, abbiamo bisogno di capire le righe finali. Per fare questo, abbiamo bisogno di definire esplicitamente qual è l'ordine dei tipi, poiché è possibile iniziare dallo stesso dt e ottenere risultati diversi, se l'ordine è cambiato (questo è ciò che fa la parte match). Una volta che avete l'ordine numerico, se il diff è inferiore o uguale a zero, che significa che sarà una nuova riga nella nuova tabella:

dt[, rid := match(type, c('big', 'medium', 'small'))][, row := cumsum(diff(c(0, rid)) <= 0)] 

Questo è ciò che i dati appare come ora:

dt 
#  type category rid row 
# 1: big  a 1 0 
# 2: medium  b 2 0 
# 3: small  c 3 0 
# 4: small  d 3 1 
# 5: medium  e 2 2 
# 6: small  f 3 2 
# 7: small  g 3 3 
# 8: big  h 1 4 
# 9: medium  i 2 4 
#10: small  j 3 4 
#11: small  k 3 5 

Qui è nella forma che hai richiesto:

na.locf(dcast(dt, row ~ type, value.var = "category")) 
# row big medium small 
# 1: 0 a  b  c 
# 2: 1 a  b  d 
# 3: 2 a  e  f 
# 4: 3 a  e  g 
# 5: 4 h  i  j 
# 6: 5 h  i  k 
+0

Grazie mille ragazzi ...!) ... mi chiedo come fai a venire con queste risposte, è come esperienza o solo talento? ... che tipo di sfondi hai? –

Problemi correlati