【问题标题】:Get the last row of a previous group in data.table获取 data.table 中上一个组的最后一行
【发布时间】:2016-11-12 03:38:52
【问题描述】:

这是我的数据表的样子:

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)]

无济于事。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    你可以这样做

    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]
    

    这样我们就不会计算每个组的班次。或者,我们可以在 cmets 中采纳 Frank 的好建议并执行以下操作。

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

    【讨论】:

    • 您正在使用 by=Group 2 次。第一个和第二个在做什么? $V1的意义是什么?
    • @gibbz00 - 我添加了一些解释。希望对您有所帮助。
    • 您正在为每个组一次又一次地计算shift(dt[, last(Product), by = Group]$V1)。我可能会做dt[dt[, last(Product), by = Group][, v := shift(V1)], on="Group", newcol := i.v]
    • @Frank - 我认为shifted &lt;- shift(dt[, last(Product), Group]$V1); dt[, newcol := shifted[.GRP], by = Group] 也可以,因为它在数据表调用之外。
    【解决方案2】:

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

    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
    

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

    这也应该很快,因为没有调用任何逻辑来获取最后一个组的值;它只是依赖于按顺序运行的组(他们这样做)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-06
      相关资源
      最近更新 更多