满足条件时,滞后向量加 1,同时重置为 0

kss*_*kss 1 r lag cumsum

我有一系列治疗,每天一次(二进制),比如:

trt <- c(0, 0, 1, 0, 0, 0, 1, 0, 0)
Run Code Online (Sandbox Code Playgroud)

我想创建一个向量days_since,即:

  1. 是 NA 直到第一次治疗。
  2. 是 0 哪里trt是 1
  3. 计算自上次治疗以来的天数

所以,输出days_since应该是:

days_since <- c(NA, NA, 0, 1, 2, 3, 0, 1, 2)
Run Code Online (Sandbox Code Playgroud)

我将如何在 R 中做到这一点?为了得到days_since,我基本上需要滞后一个元素并加 1,但每次原始向量 ( trt) 为 1时都重置。如果这在没有 for 循环的情况下可行,那将是理想的,但不是绝对必要的。

Tho*_*ing 5

也许你可以试试下面的代码

v <- cumsum(trt)
replace(ave(trt,v,FUN = seq_along)-1,v<1,NA)
Run Code Online (Sandbox Code Playgroud)

这使

[1] NA NA  0  1  2  3  0  1  2
Run Code Online (Sandbox Code Playgroud)

解释

  • 首先,我们申请cumsumtrt治疗进行分组
> v <- cumsum(trt)
> v
[1] 0 0 1 1 1 1 2 2 2
Run Code Online (Sandbox Code Playgroud)
  • 其次,使用ave有助于在每个组中添加顺序索引
> ave(trt,v,FUN = seq_along)-1
[1] 0 1 0 1 2 3 0 1 2
Run Code Online (Sandbox Code Playgroud)
  • 最后,由于该值NA在第一次处理之前,这意味着v == 1出现之前的所有值都应替换为NA。因此我们使用replace,索引逻辑如下v < 1
> replace(ave(trt,v,FUN = seq_along)-1,v<1,NA)
[1] NA NA  0  1  2  3  0  1  2
Run Code Online (Sandbox Code Playgroud)


akr*_*run 5

我们也可以使用

(NA^!cummax(trt)) * sequence(table(cumsum(trt)))-1
#[1] NA NA  0  1  2  3  0  1  2
Run Code Online (Sandbox Code Playgroud)

或与rowiddata.table

library(data.table)
(NA^!cummax(trt)) *rowid(cumsum(trt))-1
#[1] NA NA  0  1  2  3  0  1  2
Run Code Online (Sandbox Code Playgroud)