【问题标题】:Merging two tables where one column is substring of the other in R合并两个表,其中一列是 R 中另一列的子字符串
【发布时间】:2019-07-05 08:07:52
【问题描述】:

我有两个 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,但很难正确匹配算法。

【问题讨论】:

    标签: r merge fuzzyjoin


    【解决方案1】:

    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 年 3 月 17 日创建

    【讨论】:

    • 不错,优雅的解决方案。将保留以备将来参考。谢谢!
    【解决方案2】:

    您可以使用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 || "%"
    ')
    

    【讨论】:

    • 因此,这实际上适用于左连接,但我想将所有行保留在 sub_df1 data.frame 中,当我尝试外连接时,我收到错误 RIGHT and FULL OUTER JOINs are not currently supported。有没有办法解决这个问题?
    • 您可以将sub_df2 two left join sub_df1 one替换为sub_df1 one left join sub_df2 two
    • 哈哈,你在打字的时候就这么做了……谢谢!
    猜你喜欢
    • 2019-09-20
    • 2021-07-28
    • 1970-01-01
    • 2023-02-17
    • 2012-11-23
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多