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

Ald*_*eja 5 r categories reshape 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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我有一个类别层次结构:所有行的'big'类型相同,直到看到后面的'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
Run Code Online (Sandbox Code Playgroud)

如您所见,每个类别仅在找到相同类别的寄存器时发生更改,订单对于设置此类别非常重要.

你觉得有没有办法在不使用for的情况下做到这一点?

A5C*_*2T1 8

这是您可以使用的方法.你需要na.locf从"动物园":

library(data.table)
library(zoo)
Run Code Online (Sandbox Code Playgroud)

首先,我们需要弄清楚最后的行.要做到这一点,我们需要明确定义类型的顺序,因为dt如果顺序发生了变化(这就是match部件的作用),你可以从相同的结果开始并得到不同的结果.一旦你有了数字顺序,如果diff小于或等于零,这意味着它将成为新表中的新行:

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

这就是现在的数据:

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
Run Code Online (Sandbox Code Playgroud)

这是您要求的形式:

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
Run Code Online (Sandbox Code Playgroud)