我有一个简单的数据帧,如下所示:
hai_dispense_number hai_atc date_of_claim hai_age
1 tom A10A 2011-11-01 42
2 tom A10B 2011-11-01 42
3 tom G10R 2011-11-01 42
4 tom A10A 2012-02-02 42
5 tom A10A 2012-04-03 42
6 mary A10A 2012-02-02 36
7 mary A10A 2012-03-02 36
8 mary G123 2012-03-02 36
9 mary E123 2012-05-02 36
10 mary T123 2012-07-02 36
11 mary A10A 2012-08-02 43
12 sue GR123 2012-03-02 43
13 sue GR123 2012-03-08 43
14 sue GR123 2012-09-03 43
15 sue GR123 2012-10-01 43
16 sue GR123 2012-03-02 43
17 pat A10A 2012-01-02 52
18 pat GR123 2011-11-12 52
19 pat A10A 2012-03-03 52
20 pat GR123 2012-01-01 52
21 pat A10A 2012-05-06 52
我只想从2012-01-01开始隔离代码为A10A的人,而不是在2011年。在上面的数据帧中,有一些人在任何阶段都没有代码A10A,所以我也想去掉他们。所以最后,我只想得到帕特和玛丽的数据。以下是我的操作方法:
步骤1:指定"索引日期"。换句话说,2012年第一次有人拿到代码A10A
dt2<- data.table(dff,key=c('hai_dispense_number','date_of_claim'))
dt2[,date_of_claim := as.Date(date_of_claim)]
dt2[grepl('^A10A*?', as.character(dt2$hai_atc))& between(date_of_claim,as.Date("2012-01-01"),as.Date("2012-12-31")),
index := as.character(min(date_of_claim))
, by=c('hai_dispense_number','hai_atc')] #
dt2$index<-as.Date(dt2$index, origin='1970-01-01')
dt2$hai_atc<-as.character(dt2$hai_atc)
步骤2:创建索引日期会为不是A10A或发生在2012-01之前的行创建一些NA值。我需要用每个人唯一的索引日期填写这个NA值。这段代码通常有效,但由于这些数据的原因,我不断收到错误
dt2[, index := index[!is.na(index)][[1]], by=hai_dispense_number] ##gives the index date for each person to each of their individual rows of data
Error in index[!is.na(index)][[1]] : subscript out of bounds
步骤3、4和5:我通常可以从这里开始,找出2011年谁的代码为A10A,然后排除他们。但我的过程被上述错误打断了。
我看了这一页:下标越界-一般定义和解决方案?并尝试运行他们推荐的测试:但看起来变量索引没有多余的行。也许我测试不正确。
如果有人能解释为什么会发生上述情况,我将不胜感激。非常感谢。
使用any
函数可以更容易地实现您想要的。使用any(hai_atc=="A10A")
,您可以为所有拥有A10A
的人创建一个逻辑向量,使用!any(hai_atc=="A10A" & year(date_of_claim) == 2011)
,您可以将2011年拥有该代码的人的向量更新为FALSE
。使用[idx==TRUE]
,您只过滤所需的案例,使用[,idx:=NULL]
,您可以删除idx
列:
newDT <- DT[, idx := any(hai_atc=="A10A") & !any(hai_atc=="A10A" & year(date_of_claim) == 2011),
by = hai_dispense_number
][idx==TRUE][,idx:=NULL]
这导致:
> newDT
hai_dispense_number hai_atc date_of_claim hai_age
1: mary A10A 2012-02-02 36
2: mary A10A 2012-03-02 36
3: mary G123 2012-03-02 36
4: mary E123 2012-05-02 36
5: mary T123 2012-07-02 36
6: mary A10A 2012-08-02 43
7: pat A10A 2012-01-02 52
8: pat GR123 2011-11-12 52
9: pat A10A 2012-03-03 52
10: pat GR123 2012-01-01 52
11: pat A10A 2012-05-06 52
针对您的评论:您可能希望使用像dt2[, index := index[!is.na(index)][1], by=hai_dispense_number]
一样的单方括号(即:[ ]
)。此外,您的代码可以简化为:
dt2 <- data.table(mydf,key=c('hai_dispense_number','date_of_claim'))
dt2[, date_of_claim := as.Date(date_of_claim)]
dt2[grepl('^A10A*?', hai_atc) & between(date_of_claim, as.Date("2012-01-01"), as.Date("2012-12-31")),
index := min(date_of_claim), by=.(hai_dispense_number,hai_atc)]
dt2[, index := index[!is.na(index)][1], by=hai_dispense_number]
然而,这并没有给出您所描述的结果:
> dt2
hai_dispense_number hai_atc date_of_claim hai_age index
1: mary A10A 2012-02-02 36 2012-02-02
2: mary A10A 2012-03-02 36 2012-02-02
3: mary G123 2012-03-02 36 2012-02-02
4: mary E123 2012-05-02 36 2012-02-02
5: mary T123 2012-07-02 36 2012-02-02
6: mary A10A 2012-08-02 43 2012-02-02
7: pat GR123 2011-11-12 52 2012-01-02
8: pat GR123 2012-01-01 52 2012-01-02
9: pat A10A 2012-01-02 52 2012-01-02
10: pat A10A 2012-03-03 52 2012-01-02
11: pat A10A 2012-05-06 52 2012-01-02
12: sue GR123 2012-03-02 43 <NA>
13: sue GR123 2012-03-02 43 <NA>
14: sue GR123 2012-03-08 43 <NA>
15: sue GR123 2012-09-03 43 <NA>
16: sue GR123 2012-10-01 43 <NA>
17: tom A10A 2011-11-01 42 2012-02-02
18: tom A10B 2011-11-01 42 2012-02-02
19: tom G10R 2011-11-01 42 2012-02-02
20: tom A10A 2012-02-02 42 2012-02-02
21: tom A10A 2012-04-03 42 2012-02-02
您的代码没有得到所需结果的原因是,您没有排除2011年具有A10A
的组。any
函数是专门为实现您所描述的逻辑操作而设计的。
此外,通过使用any
函数,您可以以更简单的方式获得所需的结果。这也适用于更复杂的数据集。在any
:中使用grepl
也不是问题
newDT2 <- DT[, idx := any(grepl('^A10A*?', hai_atc)) & !any(grepl('^A10A*?', hai_atc) & year(date_of_claim) == 2011),
by = hai_dispense_number
][idx==TRUE][,idx:=NULL]
它给出了相同的结果:
> identical(newDT, newDT2)
[1] TRUE