如何根据R中两个不同变量的条件提取数据

如何根据R中两个不同变量的条件提取数据,r,date,group-by,conditional-statements,R,Date,Group By,Conditional Statements,我有一个包含患者id、药物代码、处方日期的100个观察数据集。我想创建一个新的列“索引日期”,它是患者第三次更换药物的日期 PatientID DrugCode Prescriptiondate A1 3 07-08-2014 A1 3 08-09-2014 A1 7 19-09-2014 A1 5 30-09-2014 A2 4 11-07-2014 A2 4 21-07-2014 A2 3 13-08-2

我有一个包含患者id、药物代码、处方日期的100个观察数据集。我想创建一个新的列“索引日期”,它是患者第三次更换药物的日期

PatientID   DrugCode    Prescriptiondate   
A1  3   07-08-2014   
A1  3   08-09-2014   
A1  7   19-09-2014   
A1  5   30-09-2014  
A2  4   11-07-2014  
A2  4   21-07-2014  
A2  3   13-08-2014  
A2  5   26-08-2014  
A2  5   30-09-2014  
A3  2   16-08-2014  
A3  3   17-09-2014  
A4  5   08-06-2014  
A4  5   29-06-2014  
A4  6   20-08-2014  
A4  6   24-09-2014  
A4  4   22-10-2014  
A4  4   25-10-2014   
数据集应如下所示:

PatientID   DrugCode    Prescriptiondate    IndexDate  
A1  3   07-08-2014  30-09-2014  
A1  3   08-09-2014  30-09-2014  
A1  7   19-09-2014  30-09-2014  
A1  5   30-09-2014  30-09-2014  
A2  4   11-07-2014  26-08-2014  
A2  4   21-07-2014  26-08-2014  
A2  3   13-08-2014  26-08-2014  
A2  5   26-08-2014  26-08-2014  
A2  5   30-09-2014  26-08-2014  
A3  2   16-08-2014  NA  
A3  3   17-09-2014  NA  
A4  5   08-06-2014  22-10-2014  
A4  5   29-06-2014  22-10-2014  
A4  6   20-08-2014  22-10-2014  
A4  6   24-09-2014  22-10-2014  
A4  4   22-10-2014  22-10-2014  
A4  4   25-10-2014  22-10-2014 
在上述病例中,患者A1和A2分别于2014年9月30日和2014年8月26日第三次将药物更换为药物5;A3未第三次更换药物,A4已于2014年10月22日更换为药物4,因此索引日期应分别为2014年9月30日、2014年8月26日、2014年10月22日


如果有人可以帮助编写此类问题的代码,请联系我们

这是一种可能的
dplyr
解决方案:

df %>% group_by(PatientID) %>% mutate(IndexDate = Prescriptiondate[match(unique(DrugCode)[3], DrugCode)])
# Source: local data frame [17 x 4]
# Groups: PatientID
# 
#    PatientID DrugCode Prescriptiondate  IndexDate
# 1         A1        3       07-08-2014 30-09-2014
# 2         A1        3       08-09-2014 30-09-2014
# 3         A1        7       19-09-2014 30-09-2014
# 4         A1        5       30-09-2014 30-09-2014
# 5         A2        4       11-07-2014 26-08-2014
# 6         A2        4       21-07-2014 26-08-2014
# 7         A2        3       13-08-2014 26-08-2014
# 8         A2        5       26-08-2014 26-08-2014
# 9         A2        5       30-09-2014 26-08-2014
# 10        A3        2       16-08-2014         NA
# 11        A3        3       17-09-2014         NA
# 12        A4        5       08-06-2014 22-10-2014
# 13        A4        5       29-06-2014 22-10-2014
# 14        A4        6       20-08-2014 22-10-2014
# 15        A4        6       24-09-2014 22-10-2014
# 16        A4        4       22-10-2014 22-10-2014
# 17        A4        4       25-10-2014 22-10-2014
我想这和
数据表的想法是一样的

dt[, IndexDate := Prescriptiondate[match(unique(DrugCode)[3], DrugCode)], PatientID]
#    PatientID DrugCode Prescriptiondate  IndexDate
#  1:        A1        3       07-08-2014 30-09-2014
#  2:        A1        3       08-09-2014 30-09-2014
#  3:        A1        7       19-09-2014 30-09-2014
#  4:        A1        5       30-09-2014 30-09-2014
#  5:        A2        4       11-07-2014 26-08-2014
#  6:        A2        4       21-07-2014 26-08-2014
#  7:        A2        3       13-08-2014 26-08-2014
#  8:        A2        5       26-08-2014 26-08-2014
#  9:        A2        5       30-09-2014 26-08-2014
# 10:        A3        2       16-08-2014         NA
# 11:        A3        3       17-09-2014         NA
# 12:        A4        5       08-06-2014 22-10-2014
# 13:        A4        5       29-06-2014 22-10-2014
# 14:        A4        6       20-08-2014 22-10-2014
# 15:        A4        6       24-09-2014 22-10-2014
# 16:        A4        4       22-10-2014 22-10-2014
# 17:        A4        4       25-10-2014 22-10-2014

match
之所以有效,是因为一旦找到匹配项,它就会停止。因此,如果一种药物使用了很多天或一天,它不会改变结果。我们寻找第三次更改DrugCode的第一个实例
unique
之所以有效,是因为它按值的出现顺序排列。因此,
unique(x)[3]
将给出该值的第三个变化

这里有一个基本的R解决方案,无耻地窃取了Pierre Lafortune的绝妙匹配独特理念:

df <- data.frame(PatientID=c('A1','A1','A1','A1','A2','A2','A2','A2','A2','A3','A3','A4','A4','A4','A4','A4','A4'),DrugCode=c(3,3,7,5,4,4,3,5,5,2,3,5,5,6,6,4,4),Prescriptiondate=as.Date(c('07-08-2014','08-09-2014','19-09-2014','30-09-2014','11-07-2014','21-07-2014','13-08-2014','26-08-2014','30-09-2014','16-08-2014','17-09-2014','08-06-2014','29-06-2014','20-08-2014','24-09-2014','22-10-2014','25-10-2014'),'%d-%m-%Y'));
df$IndexDate <- do.call('c',by(df,df$PatientID,function(g) rep(g$Prescriptiondate[match(unique(g$DrugCode)[3],g$DrugCode)],nrow(g))));
df;
##    PatientID DrugCode Prescriptiondate  IndexDate
## 1         A1        3       2014-08-07 2014-09-30
## 2         A1        3       2014-09-08 2014-09-30
## 3         A1        7       2014-09-19 2014-09-30
## 4         A1        5       2014-09-30 2014-09-30
## 5         A2        4       2014-07-11 2014-08-26
## 6         A2        4       2014-07-21 2014-08-26
## 7         A2        3       2014-08-13 2014-08-26
## 8         A2        5       2014-08-26 2014-08-26
## 9         A2        5       2014-09-30 2014-08-26
## 10        A3        2       2014-08-16       <NA>
## 11        A3        3       2014-09-17       <NA>
## 12        A4        5       2014-06-08 2014-10-22
## 13        A4        5       2014-06-29 2014-10-22
## 14        A4        6       2014-08-20 2014-10-22
## 15        A4        6       2014-09-24 2014-10-22
## 16        A4        4       2014-10-22 2014-10-22
## 17        A4        4       2014-10-25 2014-10-22

df我在运行代码“do.call中的错误”时收到错误消息,by(df,df$PatientID,function(g)rep(g$Prescriptiondate[match(unique(g$DrugCode)[3],:“what”必须是字符串或函数“@Mayur您可能在某个点分配了
c
,这掩盖了
base::c()
函数。幸运的是,
do.call()
也接受函数参数的字符串,因此
'c'
应该可以工作。请尝试我编辑的代码,并告诉我它是否工作。(另一种方法是限定它,即
do.call(base::c,…)
)谢谢你的帮助。我能得到想要的结果。谢谢你的帮助。我能得到想要的结果。