这可能非常复杂,我怀疑需要先进的知识.我现在有两种不同类型的data.frames需要组合:
数据:
数据帧A:
按患者ID列出所有输血日期.每次输血都由一个单独的行代表,患者可以进行多次输血.不同的患者可以在同一天进行输血.
Patient ID Transfusion.Date
1 01/01/2000
1 01/30/2000
2 04/01/2003
3 04/01/2003
Run Code Online (Sandbox Code Playgroud)
B类数据帧包含其他日期的测试结果,也包括患者ID:
Patient ID Test.Date Test.Value
1 11/30/1999 negative
1 01/15/2000 700 copies/uL
1 01/27/2000 900 copies/uL
2 03/30/2003 negative
Run Code Online (Sandbox Code Playgroud)
我想要的是具有相同行数的Dataframe A(每次输入为1),并将最新的Test.Value作为单独的列.每个输血日期应该具有与输血最密切(之前)进行的测试的测试结果.
期望的输出:
- >
Patient ID Transfusion.Date Pre.Transfusion.Test
1 01/01/2000 negative
1 01/30/2000 900 copies/ul
2 04/01/2003 negative
3 04/01/2003 NA
Run Code Online (Sandbox Code Playgroud)
我认为一般策略是按患者ID对data.frames进行子集化.然后获取患者1的所有输血日期,检查哪个结果最接近每个元素的所有可用test_dates,然后返回最接近的值.
如何解释R来做到这一点?
编辑1:这是这些示例的R代码
df_A <- data.frame(MRN = c(1,1,2,3),
Transfusion.Date = as.Date(c('01/01/2000', '01/30/2000',
'04/01/2003','04/01/2003'),'%m/%d/%Y'))
df_B <- data.frame(MRN = c(1,1,1,2),
Test.Date = as.Date(c('11/30/1999', '01/15/2000', '01/27/2000',
'03/30/2003'),'%m/%d/%Y'), Test.Result = c('negative',
'700 copies/ul','900 copies/ul','negative'))
Run Code Online (Sandbox Code Playgroud)
编辑2:
为了澄清,得到的数据应该是:患者A在第X天和第Y天接受输血(对于df_A).在第X天输血之前,他最近的测试结果是X(最接近第一次输血的测试日期,在df_B中).在第Y天输血之前,他最近的测试结果是Y(在第二次输血之前,也在df_B中.df_B还包含一堆其他测试日期,最终输出不需要.
这是使用data.table滚动连接:
require(data.table)
setkey(setDT(df_A), MRN, Transfusion.Date)
setkey(setDT(df_B), MRN, Test.Date)
df_B[df_A, roll=TRUE]
# MRN Test.Date Test.Result
# 1: 1 2000-01-01 negative
# 2: 1 2000-01-30 900 copies/ul
# 3: 2 2003-04-01 negative
# 4: 3 2003-04-01 NA
Run Code Online (Sandbox Code Playgroud)
setDT转换data.frame到data.table由参考(没有任何额外的复制).这将导致df_A并且df_B现在成为data.tables.
setkey按data.table我们提供的列对其进行排序,并将这些列标记为键列,这允许我们使用基于二进制搜索的连接.
我们x[i]在键列上执行表单的连接,对于每一行i,返回匹配的行x(如果有的话,其他NA)以及i行的行.这就是我们所说的equi-join.通过添加roll = TRUE,在不匹配的情况下,最后一次观察结转(LOCF).这就是我们所说的滚动连接.按升序排序(由于setkey())确保最后一次观察是最近的日期.
HTH