【问题标题】:How to merge two data frame based on partial string match with R?如何基于与 R 的部分字符串匹配合并两个数据框?
【发布时间】:2016-04-15 16:45:59
【问题描述】:

我有两个数据框:

第一个包含大量蛋白质,对此我进行了多次计算。这里是一个例子:

>Accession  Description # Peptides A2   # PSM A2    # Peptides B2   # PSM B2    # Peptides C2   # PSM C2    # Peptides D2   # PSM D2    # Peptides E2   # PSM E2    # AAs   MW [kDa]    calc. pI
P01837  Ig kappa chain C region OS=Mus musculus PE=1 SV=1 - [IGKC_MOUSE]    10  319 8   128 8   116 7   114         106 11,8    5,41
P01868  Ig gamma-1 chain C region secreted form OS=Mus musculus GN=Ighg1 PE=1 SV=1 - [IGHG1_MOUSE]  13  251 15  122 16  116 16  108         324 35,7    7,40
P60710  Actin, cytoplasmic 1 OS=Mus musculus GN=Actb PE=1 SV=1 - [ACTB_MOUSE]   15  215 10  37  11  30  11  31  16  154 375 41,7    5,48

第二个包含感兴趣的蛋白质。这里是一个例子:

>complex    Description Accession   protein
TFIID   [TAF1_MOUSE]    Q80UV9-3    Isoform 3 of Transcription initiation factor TFIID subunit 1 OS=Mus musculus GN=Taf1 - [TAF1_MOUSE]
TFIID   [TAF2_MOUSE]    Q8C176  Transcription initiation factor TFIID subunit 2 OS=Mus musculus GN=Taf2 PE=2 SV=2 - [TAF2_MOUSE]
TFIID   [TAF3_MOUSE]    Q5HZG4  Transcription initiation factor TFIID subunit 3 OS=Mus musculus GN=Taf3 PE=1 SV=2 - [TAF3_MOUSE]

我想要做的:获取一个数据框,其中仅包含我对感兴趣的蛋白质的计算值。在第一次尝试中,我使用了:

fusion <- merge.data.frame(x=tableaucleanIPTAFXwoNA, y=sublist, by.x="Description", by.y="protein", all =FALSE)

但是,两个数据帧之间的蛋白质名称命名不同,使用合并功能不起作用。

那么,当“TAF10”是“转录起始因子 TFIID 亚基 10 OS=Mus musculus GN=Taf10 PE=1 SV=1 - [TAF10_MOUSE]”字符串文本的一部分时,如何对它进行部分匹配? 换句话说,我希望 R 只识别整个字符串的一部分。

我尝试使用 grep 函数:

idx2 <- sapply("tableaucleanIPTAFX$Description", grep, "sublist$Description")  

但是,我明白了:

as.data.frame(idx2)
[1] tableaucleanIPTAFX.Description
<0 rows> (or 0-length row.names)

我猜是,模式没有被正确识别...然后我访问了 RegExr 网站,编写了一个正则表达式,以便可以识别我的 id 名称。我发现这可以将 [TRRAP_MOUSE] 识别为

转化/转录域相关蛋白 OS=Mus musculus GN=Trrap PE=1 SV=2 - [TRRAP_MOUSE] :

 /(TRRAP_[MOUSE])\w+/g

我想知道如何将它实现到我的 id 列表(我的示例中的“描述”列)?

【问题讨论】:

  • 请提供一些示例数据。

标签: r merge match partial


【解决方案1】:

你的问题有点模糊 - 使用一些样本/foobar 数据会更好 - 所以不幸的是这个答案也是如此

试试这个:

?grep                                       # Pattern Matching and Replacement
X <- data.frame(a = letters[1:10])
grep(pattern = "c", x = X$a)                # returns position of "c": 3
grepl(pattern = "c", x = X$a)               # returns a vector of bools: [ F F T F F ... ]
X[grepl(pattern = "c", x = X$a),"a") <- "C" # replaces "c" with "C"

PS:

  • 根据您的元素名称列表的大小/脏度,我经常发现 (i) 创建一个干净的(简短且明确的)名称字典,(ii) 添加一个具有此新名称的新列每个原始列表和 (iii) 使用这些列执行 merge
  • 除了base::merge,我喜欢用dplyrjoin函数(主要是因为我喜欢他们的cheat sheet);

【讨论】:

    【解决方案2】:

    这可能对你有用,它可以处理重复:

    首先是一些虚拟数据:

    df1 <- data.frame(name=c("George", "Abraham", "Barack"), stringsAsFactors = F)
    df2 <- data.frame(president=c("Thanks, Obama (Barack)","Lincoln, Abraham, George""George Washington"), stringsAsFactors = F)
    

    使用grep在完整描述中查找代码:

    idx2 <- sapply(df1$name, grep, df2$president)
    

    如果多个描述与代码匹配,这可能会导致多个匹配,所以在这里我复制原始索引以便结果对齐:

    idx1 <- sapply(seq_along(idx2), function(i) rep(i, length(idx2[[i]])))
    

    “合并”cbind 在新索引上对齐的数据集:

    > cbind(df1[unlist(idx1),,drop=F], df2[unlist(idx2),,drop=F])
           name                president
    1    George Lincoln, Abraham, George
    1.1  George        George Washington
    2   Abraham Lincoln, Abraham, George
    3    Barack   Thanks, Obama (Barack)
    

    【讨论】:

    • 谢谢@Zelazny7,这似乎是个好主意。但是,当我尝试在 sapply() 函数中运行 grep 时,我得到了: FUN(X[[i]], ...) 中的错误:无效的正则表达式 'Superoxide dismutase [Cu-Zn] OS=Mus musculus GN =Sod1 PE=1 SV=2 - [SODC_MOUSE]',原因是“字符范围无效”。好像有些字符没有被正确识别。
    • 你必须像这样转义括号:'\[Cu-Zn\]'
    • 我发现这是解决我遇到的一个类似问题的方法,但我发现了一个问题。出于某种原因,当 df1 中的一个值与 df2 中的多个值部分匹配时,结果表中仅列出了其中的 1 个匹配项(似乎是随机的),而在表的末尾有相同的数字额外的行数作为 df1 中的行数,但不是 df1 的值,它们只有 NA 和来自 df2 的值。
    • 对于上述解决方案,如何仅保留字符串匹配最大的那些行?我想删除具有多个匹配项的重复行
    • 如果最终结果存储在变量resdo.call(rbind, by(res, res$name, function(chunk) { i &lt;- which.min(adist(chunk$name[[1]], chunk$president)) chunk[i,] }))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 2021-08-22
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 2021-01-29
    相关资源
    最近更新 更多