在R中,基于另一个表中的列值过滤表?
我在这里搜索类似的问题,但找不到答案。请你帮我实现这个任务。我有一张拥有超过10,000名患者病历的大型数据集的表格,另外还有689名患者的表格。我想过滤大表,只保留第二个表中与患者有关的记录。然后创建一个新表,将两个表分组,然后我最终得到三个表(两个过滤表和一个合并表)。在R中,基于另一个表中的列值过滤表?
============================我现在拥有的============== =======
表1(相关患者):
ID | PatientID | Record1 | Record2 | Record3
--------------------------------------------------------
1 | 7366 | 3 | 1 | 1
2 | 7362 | 3 | 1 | 1
3 | 7361 | 3 | 1 | 1
4 | 7360 | 3 | 1 | 1
5 | 7363 | 3 | 1 | 1
表2(所有的患者):
ID | PatientID | Blood | SomeRecord | Foo
--------------------------------------------------------
1 | 7316 | 06668 | 21/08/2015 | 1
2 | 7302 | 08677 | 21/08/2015 | 3
3 | 7341 | 07787 | 21/08/2015 | 2
4 | 7340 | 08977 | 21/08/2015 | 1
5 | 7313 | 07887 | 21/08/2015 | 1
6 | 7366 | 56668 | 21/08/2015 | 1
7 | 7362 | 88677 | 21/08/2015 | 3
8 | 7361 | 77787 | 21/08/2015 | 2
9 | 7360 | 98977 | 21/08/2015 | 1
10 | 7363 | 87887 | 21/08/2015 | 1
我想基于表中的一个来过滤表2患者ID。该组1和2放入一个新表中。
============================ Desired Out Put =============== ======
表2(所有患者现在过滤):
ID | PatientID | Blood | SomeRecord | Foo
--------------------------------------------------------
6 | 7366 | 56668 | 21/08/2015 | 1
7 | 7362 | 88677 | 21/08/2015 | 3
8 | 7361 | 77787 | 21/08/2015 | 2
9 | 7360 | 98977 | 21/08/2015 | 1
10 | 7363 | 87887 | 21/08/2015 | 1
表3(所有患者现在过滤所有记录分组):
ID |PatientID|Blood|SomeRecord|Foo|Record1|Record2|Record3
--------------------------------------------------------
6 | 7366 |56668|21/08/2015 |1 | 3 | 1 | 1
7 | 7362 |88677|21/08/2015 |3 | 3 | 1 | 1
8 | 7361 |77787|21/08/2015 |2 | 3 | 1 | 1
9 | 7360 |98977|21/08/2015 |1 | 3 | 1 | 1
10 | 7363 |87887|21/08/2015 |1 | 3 | 1 | 1
试试这个:
final_data<-merge(table2, table1, by =c("PatientID", "ID"), all.y = T)
filtered_table2
为什么你使用'data.table' ??几乎所有这些都是基本功能。 – MichaelChirico
您是否正在寻找PaitentID和ID上的独特记录? – SamanthaDS
这是我怎么会在data.table
做到这一点:
library(data.table)
setDT(table1) #convert each table _by reference_ to the data.table type
setDT(table2)
其实我觉得它更容易先完成你的第二个步骤。
首先,反连接:
table3 <- table2[table1, on = "PatientID", nomatch = 0L]
我们可以认为这是一个子集,因为table1
是i
;它同时是一个合并(通过使用on
证明),即我们通过PatientID
合并table1
和table2
,只保留在table1
匹配行(通过激活nomatch = 0
下降不匹配的行)
接下来,过滤table2
:
table2 <- table3[ ,names(table2), with = FALSE]
基本上,我们刚刚从table3
去除table1
所有列得到过滤table2
。
根本就是两个连接在dplyr
:
library(dplyr)
semi_join(table2,table1, by=("PatientID"))
inner_join(table2,table1, by=("PatientID"))
结果:
> semi_join(table2,table1, by=("PatientID"))
ID PatientID Blood SomeRecord Foo
1 6 7366 56668 21/08/2015 1
2 7 7362 88677 21/08/2015 3
3 8 7361 77787 21/08/2015 2
4 9 7360 98977 21/08/2015 1
5 10 7363 87887 21/08/2015 1
> inner_join(table2,table1, by=("PatientID"))
ID.x PatientID Blood SomeRecord Foo ID.y Record1 Record2 Record3
1 6 7366 56668 21/08/2015 1 1 3 1 1
2 7 7362 88677 21/08/2015 3 2 3 1 1
3 8 7361 77787 21/08/2015 2 3 3 1 1
4 9 7360 98977 21/08/2015 1 4 3 1 1
5 10 7363 87887 21/08/2015 1 5 3 1 1
数据
table1 <-read.table(text="ID PatientID Record1 Record2 Record3
1 7366 3 1 1
2 7362 3 1 1
3 7361 3 1 1
4 7360 3 1 1
5 7363 3 1 1",
header=T,stringsAsFactors =F)
table2 <-read.table(text=" ID PatientID Blood SomeRecord Foo
1 7316 06668 21/08/2015 1
2 7302 08677 21/08/2015 3
3 7341 07787 21/08/2015 2
4 7340 08977 21/08/2015 1
5 7313 07887 21/08/2015 1
6 7366 56668 21/08/2015 1
7 7362 88677 21/08/2015 3
8 7361 77787 21/08/2015 2
9 7360 98977 21/08/2015 1
10 7363 87887 21/08/2015 1",
header=T,stringsAsFactors =F)
做了这个,但是表1中有613行,表2中有6222现在我使用inner_join后行数增加到了21046?你有什么想法,为什么? –
你可以试试'right_join'吗? –
'right_join'不会'工作。这真的应该是'inner_join' –
1)无包装如果DF1和DF2是两个数据帧,则M
和M[1:5]
是必需的输出。省略线标记##如果不需要排序:
M <- merge(DF2, DF1[-1], by = "PatientID")
o <- order(M$ID) ##
M <- M[o, ] ##
,并提供:
> M[1:5]
PatientID ID Blood SomeRecord Foo
5 7366 6 56668 21/08/2015 1
3 7362 7 88677 21/08/2015 3
2 7361 8 77787 21/08/2015 2
1 7360 9 98977 21/08/2015 1
4 7363 10 87887 21/08/2015 1
> M
PatientID ID Blood SomeRecord Foo Record1 Record2 Record3
5 7366 6 56668 21/08/2015 1 3 1 1
3 7362 7 88677 21/08/2015 3 3 1 1
2 7361 8 77787 21/08/2015 2 3 1 1
1 7360 9 98977 21/08/2015 1 3 1 1
4 7363 10 87887 21/08/2015 1 3 1 1
2)sqldf
> library(sqldf)
> sqldf("select b.* from DF1 a join DF2 b using (PatientID)")
ID PatientID Blood SomeRecord Foo
1 6 7366 56668 21/08/2015 1
2 7 7362 88677 21/08/2015 3
3 8 7361 77787 21/08/2015 2
4 9 7360 98977 21/08/2015 1
5 10 7363 87887 21/08/2015 1
> sqldf("select b.*, a.* from DF1 a join DF2 b using (PatientID)")
ID PatientID Blood SomeRecord Foo ID PatientID Record1 Record2 Record3
1 6 7366 56668 21/08/2015 1 1 7366 3 1 1
2 7 7362 88677 21/08/2015 3 2 7362 3 1 1
3 8 7361 77787 21/08/2015 2 3 7361 3 1 1
4 9 7360 98977 21/08/2015 1 4 7360 3 1 1
5 10 7363 87887 21/08/2015 1 5 7363 3 1 1
注:输入是:
Lines1 <- "ID | PatientID | Record1 | Record2 | Record3
1 | 7366 | 3 | 1 | 1
2 | 7362 | 3 | 1 | 1
3 | 7361 | 3 | 1 | 1
4 | 7360 | 3 | 1 | 1
5 | 7363 | 3 | 1 | 1"
Lines2 <- " ID | PatientID | Blood | SomeRecord | Foo
1 | 7316 | 06668 | 21/08/2015 | 1
2 | 7302 | 08677 | 21/08/2015 | 3
3 | 7341 | 07787 | 21/08/2015 | 2
4 | 7340 | 08977 | 21/08/2015 | 1
5 | 7313 | 07887 | 21/08/2015 | 1
6 | 7366 | 56668 | 21/08/2015 | 1
7 | 7362 | 88677 | 21/08/2015 | 3
8 | 7361 | 77787 | 21/08/2015 | 2
9 | 7360 | 98977 | 21/08/2015 | 1
10 | 7363 | 87887 | 21/08/2015 | 1"
DF1 <- read.table(text = Lines1, header = TRUE, sep = "|", strip.white = TRUE)
DF2 <- read.table(text = Lines2, header = TRUE, sep = "|", strip.white = TRUE)
我相信你要找的词汇是反连接。 – MichaelChirico
我想你想加入使用两个字段正确吗? 'final_data SamanthaDS