在本网站的其他地方也存在类似的问题,但没有一个答案包含我需要做的所有事情。
我有一个数据框,我正在尝试改变时间。研究中的受试者可以从非治疗变为治疗,但不是另一种方式。受试者有多行治疗信息,我想找到第一次治疗,这很简单。问题是不是每个人都有治疗的发生,因此每当我运行我的算法以找到第一次出现这些人被删除。让我的问题更清楚:
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
答案 0 :(得分:3)
我们可以用不同的方式做到这一点。 data.table
的一个选项是在“ID”列分组的“处理”列上使用if/else
条件。我们检查if
治疗中没有值等于'1',然后返回Data.table(.SD
)的子集,即(if(!any(treatment==1)) .SD
)或else
即如果“处理”中的“1”值返回处理中第一个值的位置索引,该位置索引等于1(which(treatment==1)[1L]
),则获取序列(seq
)并使用该数字索引数据表的子集。 (.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
或{{1} }。在这种情况下,我得到治疗和治疗滞后之间的差异(默认情况下-
给出'滞后'值。它是数据的devel版本中的一个新函数。)
shift
使用setDT(data)[, .SD[(treatment-shift(treatment, fill=0))>=0], by = ID]
的类似方法。我们根据'ID'然后根据'处理'中当前值和之前值之间的差异对dplyr
行进行分组。
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