【问题标题】:generate numbers before an event在事件之前生成数字
【发布时间】:2026-01-29 07:20:02
【问题描述】:

我想在新列中生成导致另一列中发生事件的数字。使用 R 或 python 最直接的方法是什么?

当前数据:

var1    var2    event
0.658   72.193  0
0.641   70.217  0
0.641   40.173  0
0.652   52.687  0
0.531   50.652  0
0.529   39.497  1
0.651   29.291  0
0.634   59.548  0
0.711   51.925  0
0.635   75.772  0
0.710   53.378  1
0.660   87.744  0
0.540   62.547  0
0.618   38.050  0
0.602   60.978  1

想要的输出:

var1    var2    event   event_lead
0.658   72.193  0         -5
0.641   70.217  0         -4
0.641   40.173  0         -3
0.652   52.687  0         -2
0.531   50.652  0         -1
0.529   39.497  1          0
0.651   29.291  0         -4
0.634   59.548  0         -3
0.711   51.925  0         -2
0.635   75.772  0         -1
0.710   53.378  1          0
0.660   87.744  0         -3
0.540   62.547  0         -2
0.618   38.050  0         -1
0.602   60.978  1          0

【问题讨论】:

    标签: python r


    【解决方案1】:

    使用R,我们可以试试data.table。我们创建一个分组变量 (cumsum(event == 1)),在此基础上得到相反的序列,乘以 -1 并将其分配 (:=) 到 'event_lead'。然后,我们将该输出与逻辑向量 (!event) 相乘,这样 'event' 中的 1 就变成了 'event_lead' 的 0。

    library(data.table)
    setDT(df1)[, event_lead:=-(.N:1) ,cumsum(event == 1)
             ][, event_lead := event_lead* (!event)]
    df1
    #    var1   var2 event event_lead
    # 1: 0.658 72.193     0         -5
    # 2: 0.641 70.217     0         -4
    # 3: 0.641 40.173     0         -3
    # 4: 0.652 52.687     0         -2
    # 5: 0.531 50.652     0         -1
    # 6: 0.529 39.497     1          0
    # 7: 0.651 29.291     0         -4
    # 8: 0.634 59.548     0         -3
    # 9: 0.711 51.925     0         -2
    #10: 0.635 75.772     0         -1
    #11: 0.710 53.378     1          0
    #12: 0.660 87.744     0         -3
    #13: 0.540 62.547     0         -2
    #14: 0.618 38.050     0         -1
    #15: 0.602 60.978     1          0
    

    或者我们可以使用base R中的ave

    with(df1, ave(event, cumsum(event == 1), FUN = function(x)
                    rev(seq_along(x) )* - 1) * (!event))
    #[1] -5 -4 -3 -2 -1  0 -4 -3 -2 -1  0 -3 -2 -1  0
    

    或者正如@thelatemail 提到的那样

    with(df1, ave(event, rev(cumsum(rev(event))), 
               FUN=function(x) seq_along(x) - length(x)) ) 
    

    【讨论】:

    • 完美!非常感谢,@akrun
    • 有没有办法编辑它,以便我们可以估计事件范围之前和之后的情况?像这样说:-3 -2 -1 0 1 2 -2 -1 0 1 2 3 -3 -2 -1 0 1 2 3... etc
    • @pynewbie 是基于您展示的示例的数字。我不明白。
    • @pynewbie 你能把它作为一个新问题发布吗,因为评论中并不清楚
    • ave 答案的变体 - with(dat, ave(event, rev(cumsum(rev(event))), FUN=function(x) seq_along(x) - length(x)) )