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

问题描述

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

trt <- c(0,1,0)

我要创建一个向量days_since

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

因此,输出days_since应该是:

days_since <- c(NA,NA,2,3,2)

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

解决方法

也许您可以尝试下面的代码

v <- cumsum(trt)
replace(ave(trt,v,FUN = seq_along)-1,v<1,NA)

给出

[1] NA NA  0  1  2  3  0  1  2

说明

  • 首先,我们将cumsum上的trt应用于治疗分组
> v <- cumsum(trt)
> v
[1] 0 0 1 1 1 1 2 2 2
  • 第二,使用ave有助于在每个组中添加顺序索引
> ave(trt,FUN = seq_along)-1
[1] 0 1 0 1 2 3 0 1 2
  • 最后,由于该值在第一次处理之前为NA,所以这意味着v == 1出现之前的所有值都应替换为NA。因此,我们使用replace,索引逻辑遵循v < 1
> replace(ave(trt,NA)
[1] NA NA  0  1  2  3  0  1  2
,

我们也可以使用

(NA^!cummax(trt)) * sequence(table(cumsum(trt)))-1
#[1] NA NA  0  1  2  3  0  1  2

或者使用rowid中的data.table

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