在这个网站的其他地方也有类似的问题,但是没有一个答案包含了我需要做的所有事情。
我有一个数据,我试图将其转换为时变数据。研究对象可以从非治疗转变为治疗,但不能改变其他方式。受试者有多行治疗信息,我想找出治疗的第一次出现,这就够简单了。问题是,并不是每个人都有这种治疗,因此每当我运行我的算法来查找第一次出现的情况时,这些人就会被删除。为了使我的问题更清楚:
ID treatment start.date stop.date
1 0 01/01/2002 01/02/2002
1 0 01/02/2002 01/03/2002
1 1 01/03/2002 01/04/2002
1 0 01/04/2002 01/05/2002
2 0 01/01/2002 01/02/2002
2 0 01/02/2002 01/03/2002
3 0 01/01/2002 01/02/2002
3 1 01/02/2002 01/03/2002
3 0 01/03/2002 01/04/2002 正如你所看到的,2从来没有这种治疗方法。当我运行以下算法时,2将被删除。
data$keep <- with(data,
ave(treatment==1, ID ,FUN=function(x) if(1 %in% x) cumsum(x) else 2))
with(data, data[keep==0 | (treatment==1 & keep==1),]) 是否有任何方法来扩展此代码,以使那些没有第一次出现的代码保持和将每一行保持到第一次出现时为止?
总之,我希望我的数据如下所示:
ID treatment start.date stop.date
1 0 01/01/2002 01/02/2002
1 0 01/02/2002 01/03/2002
1 1 01/03/2002 01/04/2002
2 0 01/01/2002 01/02/2002
2 0 01/02/2002 01/03/2002
3 0 01/01/2002 01/02/2002
3 1 01/02/2002 01/03/2002发布于 2015-07-15 07:50:38
我们可以用不同的方式来做。使用data.table的一个选项是对按“ID”列分组的“处理”列使用if/else条件。我们检查if中没有值等于'1',然后返回Data.table的子集(.SD),即(if(!any(treatment==1)) .SD)或else,即,如果'1‘值在’处理‘中,返回处理中第一个值的位置指数(等于1 (which(treatment==1)[1L]) ),得到序列(seq),并将该数值索引用于datatable子集。(.SD)
library(data.table)#v1.9.5+
setDT(data)[, if(!any(treatment==1)) .SD
else .SD[seq(which(treatment==1)[1L])], by = ID]
# ID treatment start.date stop.date
#1: 1 0 01/01/2002 01/02/2002
#2: 1 0 01/02/2002 01/03/2002
#3: 1 1 01/03/2002 01/04/2002
#4: 2 0 01/01/2002 01/02/2002
#5: 2 0 01/02/2002 01/03/2002
#6: 3 0 01/01/2002 01/02/2002
#7: 3 1 01/02/2002 01/03/2002或者,一种稍微紧凑的方法是在“处理”中依赖于当前值和以前值之间的差异,并检查差异是否大于或等于0。我们可以使用diff或-。在这种情况下,我得到了处理和处理滞后之间的区别(默认情况下,shift给出“滞后”值。它是data.table开发版本中的一个新功能)
setDT(data)[, .SD[(treatment-shift(treatment, fill=0))>=0], by = ID]或者使用dplyr的类似方法。我们按“ID”进行分组,然后根据“处理”中当前值和以前值之间的差异对行进行filter。
library(dplyr)
data %>%
group_by(ID) %>%
filter(c(0, diff(treatment)) >=0)
# ID treatment start.date stop.date
#1 1 0 01/01/2002 01/02/2002
#2 1 0 01/02/2002 01/03/2002
#3 1 1 01/03/2002 01/04/2002
#4 2 0 01/01/2002 01/02/2002
#5 2 0 01/02/2002 01/03/2002
#6 3 0 01/01/2002 01/02/2002
#7 3 1 01/02/2002 01/03/2002或者是来自ave的base R
data[with(data, as.logical(ave(treatment, ID,
FUN=function(x) c(0, diff(x))>=0))),]https://stackoverflow.com/questions/31424406
复制相似问题