当寄存器的顺序决定类别时,如何重塑data.table?

时间:2016-03-18 21:52:22

标签: r data.table categories reshape

我们说我有以下数据表:

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

在这种情况下,我有一个类别层次结构:' big'所有行的类型都是相同的,直到下面的'大'看到类型。并且每种类型的行为都是相同的。

我想要的重塑必须给我以下内容:

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?

的情况下执行此操作

1 个答案:

答案 0 :(得分:8)

这是您可以使用的方法。您需要{"动物园"

中的na.locf
library(data.table)
library(zoo)

首先,我们需要找出最后的行。要做到这一点,我们需要明确定义类型的顺序,因为您可以从相同的dt开始并获得不同的结果,如果订单被更改(那是{{1部分确实)。一旦你有了数字顺序,如果diff小于或等于零,这意味着它将成为新表中的新行:

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