我有一系列治疗,每天一次(二进制),比如:
trt <- c(0, 0, 1, 0, 0, 0, 1, 0, 0)
Run Code Online (Sandbox Code Playgroud)
我想创建一个向量days_since,即:
trt是 1所以,输出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 循环的情况下可行,那将是理想的,但不是绝对必要的。
也许你可以试试下面的代码
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)
解释
cumsum对trt治疗进行分组> 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)
我们也可以使用
(NA^!cummax(trt)) * sequence(table(cumsum(trt)))-1
#[1] NA NA 0 1 2 3 0 1 2
Run Code Online (Sandbox Code Playgroud)
或与rowid从data.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)