合并两个表,其中一列是 R 中另一列的子字符串
Merging two tables where one column is substring of the other in R
我有两个 data.frames 列包含登录号
df 1 的子集:
sub_df1 <- structure(list(database = "CLO, ArrayExpress, ArrayExpress, ATCC, BCRJ, BioSample, CCLE, ChEMBL-Cells, ChEMBL-Targets, Cosmic, Cosmic, Cosmic, Cosmic-CLP, GDSC, GEO, GEO, GEO, IGRhCellID, LINCS_LDP, Wikidata",
database_accession = "CLO_0009006, E-MTAB-2770, E-MTAB-3610, CRL-7724, 0337, SAMN03471142, SH4_SKIN, CHEMBL3308177, CHEMBL2366309, 687440, 909713, 2159447, 909713, 909713, GSM887568, GSM888651, GSM1670420, SH4, LCL-1280, Q54953204"), .Names = c("database",
"database_accession"), row.names = 2L, class = "data.frame")
df 2 的子集:
sub_df2 <- structure(list(database_accession = "SH4_SKIN", G1 = -1.907138,
G2 = -7.617305, G3 = -3.750553, G4 = 2.615004, G5 = 9.751557), .Names = c("database_accession",
"G1", "G2", "G3", "G4", "G5"), row.names = 101L, class = "data.frame")
我想按 database_accession
列合并两个数据框,但问题是它们不完全匹配。 sub_df2
中的字符串是 sub_df1
.
中字符串的子字符串
我考虑过使用 fuzzyjoin,但很难找到正确的匹配算法。
您可以使用 sqldf
包并编写一个查询,使用 like
条件连接表,以测试 sub_df1
中的值是否包含 sub_df2
中的值.
library(sqldf)
sqldf('
select *
from sub_df2 two
left join sub_df1 one
on one.database_accession like "%" || two.database_accession || "%"
')
fuzzyjoin
解决方案,使用match_fun = str_detect或regex_join():
library(tidyverse); library(fuzzyjoin)
# Load data
sub_df1 <- structure(list(database = "CLO, ArrayExpress, ArrayExpress, ATCC, BCRJ, BioSample, CCLE, ChEMBL-Cells, ChEMBL-Targets, Cosmic, Cosmic, Cosmic, Cosmic-CLP, GDSC, GEO, GEO, GEO, IGRhCellID, LINCS_LDP, Wikidata", database_accession = "CLO_0009006, E-MTAB-2770, E-MTAB-3610, CRL-7724, 0337, SAMN03471142, SH4_SKIN, CHEMBL3308177, CHEMBL2366309, 687440, 909713, 2159447, 909713, 909713, GSM887568, GSM888651, GSM1670420, SH4, LCL-1280, Q54953204"), .Names = c("database", "database_accession"), row.names = 2L, class = "data.frame")
sub_df2 <- structure(list(database_accession = "SH4_SKIN", G1 = -1.907138, G2 = -7.617305, G3 = -3.750553, G4 = 2.615004, G5 = 9.751557), .Names = c("database_accession", "G1", "G2", "G3", "G4", "G5"), row.names = 101L, class = "data.frame")
# Solution
# Using fuzzy_join. Could also use regex_full_join(), which is the wrapper for match_fun = str_detect, mode = "full"
fuzzy_join(sub_df1, sub_df2, match_fun = str_detect, by = "database_accession", mode = "full") %>%
str()
#> 'data.frame': 1 obs. of 8 variables:
#> $ database : chr "CLO, ArrayExpress, ArrayExpress, ATCC, BCRJ, BioSample, CCLE, ChEMBL-Cells, ChEMBL-Targets, Cosmic, Cosmic, Cos"| __truncated__
#> $ database_accession.x: chr "CLO_0009006, E-MTAB-2770, E-MTAB-3610, CRL-7724, 0337, SAMN03471142, SH4_SKIN, CHEMBL3308177, CHEMBL2366309, 68"| __truncated__
#> $ database_accession.y: chr "SH4_SKIN"
#> $ G1 : num -1.91
#> $ G2 : num -7.62
#> $ G3 : num -3.75
#> $ G4 : num 2.62
#> $ G5 : num 9.75
由 reprex package (v0.2.1)
创建于 2019-03-17
我有两个 data.frames 列包含登录号
df 1 的子集:
sub_df1 <- structure(list(database = "CLO, ArrayExpress, ArrayExpress, ATCC, BCRJ, BioSample, CCLE, ChEMBL-Cells, ChEMBL-Targets, Cosmic, Cosmic, Cosmic, Cosmic-CLP, GDSC, GEO, GEO, GEO, IGRhCellID, LINCS_LDP, Wikidata",
database_accession = "CLO_0009006, E-MTAB-2770, E-MTAB-3610, CRL-7724, 0337, SAMN03471142, SH4_SKIN, CHEMBL3308177, CHEMBL2366309, 687440, 909713, 2159447, 909713, 909713, GSM887568, GSM888651, GSM1670420, SH4, LCL-1280, Q54953204"), .Names = c("database",
"database_accession"), row.names = 2L, class = "data.frame")
df 2 的子集:
sub_df2 <- structure(list(database_accession = "SH4_SKIN", G1 = -1.907138,
G2 = -7.617305, G3 = -3.750553, G4 = 2.615004, G5 = 9.751557), .Names = c("database_accession",
"G1", "G2", "G3", "G4", "G5"), row.names = 101L, class = "data.frame")
我想按 database_accession
列合并两个数据框,但问题是它们不完全匹配。 sub_df2
中的字符串是 sub_df1
.
我考虑过使用 fuzzyjoin,但很难找到正确的匹配算法。
您可以使用 sqldf
包并编写一个查询,使用 like
条件连接表,以测试 sub_df1
中的值是否包含 sub_df2
中的值.
library(sqldf)
sqldf('
select *
from sub_df2 two
left join sub_df1 one
on one.database_accession like "%" || two.database_accession || "%"
')
fuzzyjoin
解决方案,使用match_fun = str_detect或regex_join():
library(tidyverse); library(fuzzyjoin)
# Load data
sub_df1 <- structure(list(database = "CLO, ArrayExpress, ArrayExpress, ATCC, BCRJ, BioSample, CCLE, ChEMBL-Cells, ChEMBL-Targets, Cosmic, Cosmic, Cosmic, Cosmic-CLP, GDSC, GEO, GEO, GEO, IGRhCellID, LINCS_LDP, Wikidata", database_accession = "CLO_0009006, E-MTAB-2770, E-MTAB-3610, CRL-7724, 0337, SAMN03471142, SH4_SKIN, CHEMBL3308177, CHEMBL2366309, 687440, 909713, 2159447, 909713, 909713, GSM887568, GSM888651, GSM1670420, SH4, LCL-1280, Q54953204"), .Names = c("database", "database_accession"), row.names = 2L, class = "data.frame")
sub_df2 <- structure(list(database_accession = "SH4_SKIN", G1 = -1.907138, G2 = -7.617305, G3 = -3.750553, G4 = 2.615004, G5 = 9.751557), .Names = c("database_accession", "G1", "G2", "G3", "G4", "G5"), row.names = 101L, class = "data.frame")
# Solution
# Using fuzzy_join. Could also use regex_full_join(), which is the wrapper for match_fun = str_detect, mode = "full"
fuzzy_join(sub_df1, sub_df2, match_fun = str_detect, by = "database_accession", mode = "full") %>%
str()
#> 'data.frame': 1 obs. of 8 variables:
#> $ database : chr "CLO, ArrayExpress, ArrayExpress, ATCC, BCRJ, BioSample, CCLE, ChEMBL-Cells, ChEMBL-Targets, Cosmic, Cosmic, Cos"| __truncated__
#> $ database_accession.x: chr "CLO_0009006, E-MTAB-2770, E-MTAB-3610, CRL-7724, 0337, SAMN03471142, SH4_SKIN, CHEMBL3308177, CHEMBL2366309, 68"| __truncated__
#> $ database_accession.y: chr "SH4_SKIN"
#> $ G1 : num -1.91
#> $ G2 : num -7.62
#> $ G3 : num -3.75
#> $ G4 : num 2.62
#> $ G5 : num 9.75
由 reprex package (v0.2.1)
创建于 2019-03-17