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

How can I reshape a data.table when the order of the registers determines the category?

假设我有以下数据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

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

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

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 的方法来做到这一点?

您可以使用以下方法。您需要 "zoo":

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

首先,我们需要弄清楚最后几行。为此,我们需要明确定义类型的顺序,因为如果顺序发生变化,您可以从相同的 dt 开始并得到不同的结果(这就是 match 部分的作用).获得数字顺序后,如果差异小于或等于零,则意味着它将成为新 table:

中的新行
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