4.0.4 版 R 中的匹配函数

match function in R for version 4.0.4

我有 2 个大型数据集。一种是 DB 作为数据库,一种是 raw 作为我自己的数据:

只是 2 个数据帧的样本:

DB:
| rel.genes |        code           | description |
|    fla    | VFG002519(gbYP_109887)| sahashdkjas |
|    un     | YP_105432             | sashjkas    |

raw:
| species |   sacver | qacver |
|   saa   | YP_109887| 122134 |
|   saa   | YP_105432| 42234  |

我想将 raw 的 sacver 数据与 DB 数据帧的代码列相匹配。如果在代码的一行中找到了 sacver,它应该将相应的 "rel.genes" 从 DB 数据帧输出到原始数据帧中的新列。我用这段代码很容易习惯:

raw$genes <- DB$rel.genes[match(raw$sacver,DB$code)]

它应该产生这个 table:

| species |  sacver  | qacver | genes |
|    saa  | YP_109887| 123214 |  fla  |
|    saa  | YP_105432| 42234  |   un  |

现在我将我的 R 更新到版本 4.0.4,此代码不再有效。它没有将 rel.genes 作为输出,而是对新基因列的所有行只有“NA”。

我应该用我的代码更改什么?

match 正在寻找 完全 匹配,并且 "VFG002519(gbYP_109887)" != "YP_109887"。如果你想要部分匹配,那么我建议 fuzzyjoin:

fuzzyjoin::regex_right_join(DB, raw, by = c("code" = "sacver"))
#   rel.genes                   code description species    sacver qacver
# 1       fla VFG002519(gbYP_109887) sahashdkjas     saa YP_109887 122134
# 2        un              YP_105432    sashjkas     saa YP_105432  42234

这样做的风险是部分匹配。例如,如果存在 raw$sacver 且只有 YP_10988(没有 7),那么它将匹配。这将导致一行出现多个匹配项,或者至少出现 none 应该出现的匹配项。例如,

raw2 <- rbind(raw, data.frame(species = "saa", sacver = "YP_10988", qacver = 122135L))
raw2
#   species    sacver qacver
# 1     saa YP_109887 122134
# 2     saa YP_105432  42234
# 3     saa  YP_10988 122135

fuzzyjoin::regex_right_join(DB, raw2, by = c("code" = "sacver"))
#   rel.genes                   code description species    sacver qacver
# 1       fla VFG002519(gbYP_109887) sahashdkjas     saa YP_109887 122134
# 2        un              YP_105432    sashjkas     saa YP_105432  42234
# 3       fla VFG002519(gbYP_109887) sahashdkjas     saa  YP_10988 122135

第三行是双拼(注意122135,新的qacver是我加的)

为了减轻这种风险,将有助于改进 raw(其中包含正则表达式连接的“模式”)以包括正则表达式“单词边界”:

raw2$sacver_ptn <- paste0("\b", raw2$sacver, "\b")
raw2
#   species    sacver qacver      sacver_ptn
# 1     saa YP_109887 122134 \bYP_109887\b
# 2     saa YP_105432  42234 \bYP_105432\b
# 3     saa  YP_10988 122135  \bYP_10988\b

fuzzyjoin::regex_right_join(DB, raw2, by = c("code" = "sacver_ptn"))
#   rel.genes      code description species    sacver qacver      sacver_ptn
# 1      <NA>      <NA>        <NA>     saa YP_109887 122134 \bYP_109887\b
# 2        un YP_105432    sashjkas     saa YP_105432  42234 \bYP_105432\b
# 3      <NA>      <NA>        <NA>     saa  YP_10988 122135  \bYP_10988\b

不幸的是,在您的示例中,您有 gbYP_109887,其中 gb 不会像我们希望的那样触发单词边界。为此,我将把界限放宽到数字方面:

raw2$sacver_ptn <- paste0(raw2$sacver, "\b")
raw2
#   species    sacver qacver   sacver_ptn
# 1     saa YP_109887 122134 YP_109887\b
# 2     saa YP_105432  42234 YP_105432\b
# 3     saa  YP_10988 122135  YP_10988\b

fuzzyjoin::regex_right_join(DB, raw2, by = c("code" = "sacver_ptn"))
#   rel.genes                   code description species    sacver qacver   sacver_ptn
# 1       fla VFG002519(gbYP_109887) sahashdkjas     saa YP_109887 122134 YP_109887\b
# 2        un              YP_105432    sashjkas     saa YP_105432  42234 YP_105432\b
# 3      <NA>                   <NA>        <NA>     saa  YP_10988 122135  YP_10988\b

在这种情况下,我的新 YP_10988 匹配 DB 条目中的 none,因此它在 rel.genes.

中没有任何内容