使用 dplyr left join 合并两个数据帧?
Merging two dataframe with dplyr left join?
我有两个数据框,competitor_sheet
和left_join_prototype
,我分别称之为df1和df2,df1和df2分别包含基因和疾病ID的信息,看起来像这样:
df1:
HUGO_symbol
MeSH_ID
P53
D000310
A1BG
D0002277
ZZZ3
D000230
df2:
Gene.Name
Parent.MeSH.ID
Child.MeSH.ID
P53
D000310
D015675, D006676
HGA2
D031031
D002277
ZZZ3
D001163, D000230
D003451
如您所见,df2 的父 MeSH ID 和子 MeSH ID 中可能包含多个 ID。本质上,如果子项或父项中的任何 MeSH ID 对应于 df1 中的 MeSH ID,我要做的是将 df2 到 df1 的任何行连接起来,但前提是 Gene.Name = HUGO_symbol,最终产品应该是这样的:
HUGO_symbol
MeSH_ID
Gene.Name
Parent.Mesh.ID
Child.MeSH.ID
P53
D000310
P53
D000310
D015675, D006676
ZZZ3
D000230
ZZZ3
D001163, D00230
D003451
我已经尝试过使用 dplyr 看起来像这样的东西:
proto <- left_join(df1,df2, by = c("MeSH_ID"="Parent.MeSH.ID", "HUGO_Symbol"="Gene.Name", "MeSH_ID2"="Child.MeSH.ID"))
其中 proto
将是新的 table 但我觉得这是错误的。
一如既往,非常感谢任何帮助:)
问题是 left_join 寻找完全匹配,但没有像“匹配这个或那个”这样的东西。因此,为了达到您想要的结果,您可以
- 将
Parent.MeSH.ID
和 Child.MeSH.ID
合并到一个新列中 MeSH_ID
- 将联合列拆分为单独的 ID,例如使用
tidyr::separate_rows
。这样做可以通过 ID 加入 df。
- 使用
semi_join
过滤掉 df1 中与新创建的 df3 中匹配的行,最后执行 left_join
添加 df3 中的列。或者,如果保留 HUGO_symbol
和 Gene.Name
无关紧要,您可以使用 inner_join
. 来完成这两个步骤
df1 <- data.frame(
stringsAsFactors = FALSE,
HUGO_symbol = c("P53", "A1BG", "ZZZ3"),
MeSH_ID = c("D000310", "D0002277", "D000230")
)
df2 <- data.frame(
stringsAsFactors = FALSE,
Gene.Name = c("P53", "HGA2", "ZZZ3"),
Parent.MeSH.ID = c("D000310", "D031031", "D001163, D000230"),
Child.MeSH.ID = c("D015675, D006676", "D002277", "D003451")
)
library(dplyr)
library(tidyr)
df3 <- df2 %>%
unite("MeSH_ID", Parent.MeSH.ID, Child.MeSH.ID, sep = ", ", remove = FALSE) %>%
separate_rows(MeSH_ID, sep = ", ")
semi_join(df1, df3, by = c("HUGO_symbol" = "Gene.Name", "MeSH_ID")) %>%
left_join(df3)
#> Joining, by = "MeSH_ID"
#> HUGO_symbol MeSH_ID Gene.Name Parent.MeSH.ID Child.MeSH.ID
#> 1 P53 D000310 P53 D000310 D015675, D006676
#> 2 ZZZ3 D000230 ZZZ3 D001163, D000230 D003451
我有两个数据框,competitor_sheet
和left_join_prototype
,我分别称之为df1和df2,df1和df2分别包含基因和疾病ID的信息,看起来像这样:
df1:
HUGO_symbol | MeSH_ID |
---|---|
P53 | D000310 |
A1BG | D0002277 |
ZZZ3 | D000230 |
df2:
Gene.Name | Parent.MeSH.ID | Child.MeSH.ID |
---|---|---|
P53 | D000310 | D015675, D006676 |
HGA2 | D031031 | D002277 |
ZZZ3 | D001163, D000230 | D003451 |
如您所见,df2 的父 MeSH ID 和子 MeSH ID 中可能包含多个 ID。本质上,如果子项或父项中的任何 MeSH ID 对应于 df1 中的 MeSH ID,我要做的是将 df2 到 df1 的任何行连接起来,但前提是 Gene.Name = HUGO_symbol,最终产品应该是这样的:
HUGO_symbol | MeSH_ID | Gene.Name | Parent.Mesh.ID | Child.MeSH.ID |
---|---|---|---|---|
P53 | D000310 | P53 | D000310 | D015675, D006676 |
ZZZ3 | D000230 | ZZZ3 | D001163, D00230 | D003451 |
我已经尝试过使用 dplyr 看起来像这样的东西:
proto <- left_join(df1,df2, by = c("MeSH_ID"="Parent.MeSH.ID", "HUGO_Symbol"="Gene.Name", "MeSH_ID2"="Child.MeSH.ID"))
其中 proto
将是新的 table 但我觉得这是错误的。
一如既往,非常感谢任何帮助:)
问题是 left_join 寻找完全匹配,但没有像“匹配这个或那个”这样的东西。因此,为了达到您想要的结果,您可以
- 将
Parent.MeSH.ID
和Child.MeSH.ID
合并到一个新列中MeSH_ID
- 将联合列拆分为单独的 ID,例如使用
tidyr::separate_rows
。这样做可以通过 ID 加入 df。 - 使用
semi_join
过滤掉 df1 中与新创建的 df3 中匹配的行,最后执行left_join
添加 df3 中的列。或者,如果保留HUGO_symbol
和Gene.Name
无关紧要,您可以使用inner_join
. 来完成这两个步骤
df1 <- data.frame(
stringsAsFactors = FALSE,
HUGO_symbol = c("P53", "A1BG", "ZZZ3"),
MeSH_ID = c("D000310", "D0002277", "D000230")
)
df2 <- data.frame(
stringsAsFactors = FALSE,
Gene.Name = c("P53", "HGA2", "ZZZ3"),
Parent.MeSH.ID = c("D000310", "D031031", "D001163, D000230"),
Child.MeSH.ID = c("D015675, D006676", "D002277", "D003451")
)
library(dplyr)
library(tidyr)
df3 <- df2 %>%
unite("MeSH_ID", Parent.MeSH.ID, Child.MeSH.ID, sep = ", ", remove = FALSE) %>%
separate_rows(MeSH_ID, sep = ", ")
semi_join(df1, df3, by = c("HUGO_symbol" = "Gene.Name", "MeSH_ID")) %>%
left_join(df3)
#> Joining, by = "MeSH_ID"
#> HUGO_symbol MeSH_ID Gene.Name Parent.MeSH.ID Child.MeSH.ID
#> 1 P53 D000310 P53 D000310 D015675, D006676
#> 2 ZZZ3 D000230 ZZZ3 D001163, D000230 D003451