2016-03-18 28 views
5

比方說,我有以下數據表:如何在寄存器的順序決定類別時重新設置data.table?

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 

在這種情況下,我有一個分類層級:「大」型是所有行相同,直到下「大」類型能夠被看見。每種類型的行爲都是一樣的。

我想一定要給我以下的重塑:

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 

正如你可以看到每個類別只改變時,同一類別的寄存器被找到,爲了設置這個類別是非常重要的。

你認爲有沒有辦法做到這一點而不使用for?

回答

8

以下是您可以使用的方法。你需要從na.locf「動物園」:

library(data.table) 
library(zoo) 

首先,我們需要弄清楚的最後行。爲此,我們需要明確定義類型的順序,因爲您可以從相同的dt開始並獲得不同的結果(如果訂單發生更改)(這就是match部件的作用)。一旦你的數字順序,如果差異小於或等於零,這意味着它要在新表中的新行:

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

這就是數據看起來像現在:

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 

這是在表單您要求:

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

謝謝你這麼多傢伙...!)...我不知道你怎麼設法想出這些答案,是它喜歡經驗還是才華?......你有什麼樣的背景? –

相關問題