我有一个简单的数据框如下:
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所以我会也喜欢摆脱它们。所以最后,我想要只有pat和mary的数据。我是这样做的:
步骤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,然后排除它们。但我的过程被上述错误打断了。
我查看了这个页面:Subscript out of bounds - general definition and solution?并尝试运行他们推荐的测试:但看起来我的变量索引没有额外的行。也许我没有正确测试。
如果有人能说清楚为什么会发生这种情况,我会非常感激。谢谢!
答案 0 :(得分:3)
使用any
功能可以更轻松地实现您想要的功能。使用any(hai_atc=="A10A")
,您可以为拥有A10A
和!any(hai_atc=="A10A" & year(date_of_claim) == 2011)
的所有人创建一个逻辑向量,以便为那些2011年拥有该代码的人FALSE
更新该vecor。使用[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
功能,您可以更简单的方式获得所需的结果。这也适用于更复杂的数据集。在grepl
内使用any
也不是问题:
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