【问题标题】:Carry data.table column values forward when conditions are met满足条件时将 data.table 列值前移
【发布时间】:2017-04-18 06:22:07
【问题描述】:

我有一个包含两列的 data.table。

dt = data.table(a = c(0,0,-1,rep(0,3),-1,1), b = c(1,2,3,2,4,2,4,5))
> dt
    a b
1:  0 1
2:  0 2
3: -1 3
4:  0 2
5:  0 4
6:  0 2
7: -1 4
8:  1 5

我需要做的是任何时候列 a == -1 我需要将 b 列中的值结转到下一行 a == -1 之前的位置。如果没有更多的-1,那么b列中的值需要一直持续到data.table的末尾

这是我希望的结果

    a b
1:  0 1
2:  0 2
3: -1 3
4:  0 3
5:  0 3
6:  0 3
7: -1 4
8:  1 4

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    好吧,这并不像我最初想象的那么难。如有必要,我可以删除这个问题,但我在 stackoverflow 上没有找到类似的东西,所以我现在只发布我的解决方案。

    第一个解决方案存在问题。这实际上符合我的预期,但我确信有一种更快的方法来计算它。

    library(data.table)
    dt = data.table(a = c(0,0,-1,rep(0,3),-1,1), b = c(1,2,3,2,4,2,4,5))
    
    indices = which(dt$a == -1)
    values = dt$b[indices]
    
    dt[ , "tmp" := findInterval(1:nrow(dt), indices)]
    
    dt$b = mapply(function(tmp, b){
                          if(tmp == 0){
                            return(b)
                          }else{
                            return(values[tmp])
                          }
                        }, dt$tmp, dt$b)
    
    dt[ , "tmp" := NULL]
    
    > dt
        a b
    1:  0 1
    2:  0 2
    3: -1 3
    4:  0 3
    5:  0 3
    6:  0 3
    7: -1 4
    8:  1 4
    

    感谢@Frank 提供了更好的解决方案

    dt[, tmp := cumsum(a==-1)][tmp > 0L, b := first(b), by=tmp][, tmp := NULL ]
    

    【讨论】:

    • 仅供参考,更快更标准:dt[, b := first(b), by=cumsum(a==-1)]
    • @Frank 谢谢,这是一个更好的解决方案
    • @Frank 实际上,这不太行。它也将第一个 -1 之前的值更改为该组中的最小值。这些值应保持不变。
    • 啊,好点子。鉴于此,我想dt[, tmp := cumsum(a==-1)][tmp > 0L, b := first(b), by=tmp][, tmp := NULL ] 是一种方法。
    【解决方案2】:

    在基础 R 中可能是这样的:

    x <- c(which(dt==-1), nrow(dt)+1)
    #[1] 3 7 9
    dt[x[1]:nrow(dt),]$b <- rep(dt$b[head(x,-1)], diff(x))
    
    #   a b
    #1:  0 1
    #2:  0 2
    #3: -1 3
    #4:  0 3
    #5:  0 3
    #6:  0 3
    #7: -1 4
    #8:  1 4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-27
      • 1970-01-01
      • 2015-03-21
      • 2021-06-26
      • 2019-11-11
      • 2016-02-05
      • 2021-05-19
      • 2016-12-04
      相关资源
      最近更新 更多