在data.table中获取前一组的最后一行

13

这是我的数据表的样子:

library(data.table)
dt <- fread('
    Product  Group    LastProductOfPriorGroup
    A          1          NA
    B          1          NA
    C          2          B
    D          2          B
    E          2          B
    F          3          E
    G          3          E
')

LastProductOfPriorGroup列是我想要的列。我正在尝试获取上一组的最后一行中的乘积。因此,在前两行中,没有先前的组,因此它是NA。在第三行中,先前的第1组中最后一行的乘积是B。我试图通过这样做来实现

dt[,LastGroupProduct:= shift(Product,1), by=shift(Group,1)]
无济于事。
2个回答

17

你可以做到

dt[, newcol := shift(dt[, last(Product), by = Group]$V1)[.GRP], by = Group]
这将导致以下更新的dt,其中newcol与您所需的过长列名匹配。 ;)
   Product Group LastProductOfPriorGroup newcol
1:       A     1                      NA     NA
2:       B     1                      NA     NA
3:       C     2                       B      B
4:       D     2                       B      B
5:       E     2                       B      B
6:       F     3                       E      E
7:       G     3                       E      E

让我们从内到外分解这段代码。我将使用...来表示累加的代码:

  • dt[, last(Product), by = Group]$V1 会得到每个组的最后一个值作为字符向量。
  • shift(...) 移动前一个调用中的字符向量。
  • dt[, newcol := ...[.GRP], by = Group]Group 分组,并使用内部的 .GRP 值进行索引。

更新:Frank提出了一个很好的观点,即上面的代码对每个组都重复计算了移动操作。为了避免这种情况,我们可以选择

shifted <- shift(dt[, last(Product), Group]$V1)
dt[, newcol := shifted[.GRP], by = Group]

为了不为每个组计算位移量,或者我们可以采用 Frank 在评论中提出的好建议并执行以下操作。

dt[dt[, last(Product), by = Group][, v := shift(V1)], on="Group", newcol := i.v] 

你正在使用by=Group两次。第一个是做什么的?第二个是做什么的?$V1的意义是什么? - gibbz00
1
@gibbz00 - 我添加了一些解释。希望有所帮助。 - Rich Scriven
1
你需要为每个分组计算 shift(dt[, last(Product), by = Group]$V1),这样做会重复计算。我会选择使用 dt[dt[, last(Product), by = Group][, v := shift(V1)], on="Group", newcol := i.v] - Frank
1
@Frank - 我认为 shifted <- shift(dt[, last(Product), Group]$V1);dt[, newcol := shifted[.GRP], by = Group] 也可以,因为它在数据表调用之外。 - Rich Scriven

11

另一种方法是将最后一组的值保存在一个变量中。

this = NA_character_    # initialize
dt[, LastProductOfPriorGroup:={ last<-this; this<-last(Product); last }, by=Group]
dt
   Product Group LastProductOfPriorGroup
1:       A     1                      NA
2:       B     1                      NA
3:       C     2                       B
4:       D     2                       B
5:       E     2                       B
6:       F     3                       E
7:       G     3                       E

NB: last()是一个data.table函数,用于返回向量的最后一项(在本例中为Product列)。

由于没有调用逻辑来获取最后一组的值,因此这也应该很快,它只依赖于按顺序运行的分组(它们确实按顺序运行)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接