2016-03-18 24 views
5

Powiedzmy mam następującą tabelę danych:Jak zmienić kształt tabeli data.table, gdy kolejność rejestrów określa kategorię?

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 

W tym przypadku mam hierarchię kategorii: „Big” typ jest taki sam dla wszystkich wierszy, aż po „wielkim” typ jest postrzegana. A zachowanie jest takie samo dla każdego typu.

Reshape Chcę musi dać mi następujące:

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 

Jak widać każdą kategorię zmienia się tylko gdy rejestr tej samej kategorii zostanie znaleziony, kolejność jest istotna, aby ustawić tę kategorię.

Czy sądzisz, że istnieje sposób na zrobienie tego bez użycia for?

Odpowiedz

8

Oto podejście, z którego można skorzystać. Musisz na.locf z „zoo”:

library(data.table) 
library(zoo) 

Po pierwsze, musimy dowiedzieć się końcowe wiersze. Aby to zrobić, musimy jednoznacznie zdefiniować kolejność typów, ponieważ możesz zacząć od tego samego dt i uzyskać różne wyniki, jeśli kolejność zostanie zmieniona (tak robi część match). Gdy masz kolejności numerycznej, jeżeli diff jest mniejsza lub równa zeru, to znaczy, że będzie nowy rząd w nowej tabeli:

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

To, co dane wygląda teraz:

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 

Tutaj jest on w postaci już wniosek:

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

bardzo dziękuję chłopaki ...:) ... zastanawiam się, w jaki sposób uda Ci się wymyślić tych odpowiedzi jest to jak doświadczenie czy po prostu talent? ... jakie masz pochodzenie? –