在 R 中进行多重匹配后,如何从 2 个数据框中乘以列值

How to do multiply column value from 2 dataframe after doing multiple match in R

我有 2 个数据框。我想将 df_1 中的单元格值 det_iddf_2Id_1Id_2 相匹配。如果我得到任何匹配项,那么我会将 df_1multiplierdf_2sim 相乘。数据帧结构如下

df_1

  id                                  det_id multiplier
1  1     FID00119 _ FSID012160 _ Riboflavine       0.20
2  2     FID00099 _ FSID012160 _ Riboflavine       0.30
3  3          FID00120 _ FSID009721 _ Lignin       0.50
4  4 FID00120 _ FSID012362 _ beta-Sitosterol       0.20
5  5       FID00038 _ FSID013505 _ Taraxerol       0.70
6  6 FID00087 _ FSID012362 _ beta-Sitosterol       0.90
7  7     FID00094 _ FSID013269 _ Cholesterol       0.05

df_2

                                        Id_1                                    Id_2  sim
1                                    ID00309                                 ID00314 0.55
2                                    ID00309                                 ID00315 0.66
3                                    ID00309     FID00119 _ FSID012160 _ Riboflavine 0.97
4                                    ID00309     FID00099 _ FSID012160 _ Riboflavine 0.66
5                                    ID00310          FID00120 _ FSID009721 _ Lignin 0.55
6                                    ID00311 FID00120 _ FSID012362 _ beta-Sitosterol 0.34
7                                    ID00312       FID00038 _ FSID013505 _ Taraxerol 0.44
8                                    ID00313 FID00087 _ FSID012362 _ beta-Sitosterol 0.55
9                                    ID00313     FID00094 _ FSID013269 _ Cholesterol 0.23
10         FID00038 _ FSID013505 _ Taraxerol                                 ID00910 0.00
11 FID00120 _ FSID001304 _ alpha1-Sitosterol        FID00017 _ FSID004090 _ Atropine 1.00
12   FID00087 _ FSID012362 _ beta-Sitosterol       FID00038 _ FSID013505 _ Taraxerol 0.78

我写了一个代码,只能分别匹配Id_1 or Id_2,不能同时匹配!

df_2$new_ssp <- df_2$multiplier[match(df_1$Id_1, df_1$det_id)] * df_2[-c(1, 2)] 

df_2$new_ssp <- df_2$multiplier[match(df_2$Id_2, df_1$det_id)] * df_2[-c(1, 2)]

那么,我该如何解决这些问题呢?

  1. 我想在同一代码中匹配两个 Id_1 or Id_2。例如,如果我使用我的第二个代码,那么我得到 NA for 10, 11 number rows of df_2。但是,我也想匹配 ID_1
  2. 如果 df_21 and 2 数字行不匹配,那么我想将 sim 值放在新列 new_ssp 中。
  3. 如果有多个匹配项,例如 df_212 数字行,那么我想从 df_1 中取出 maximum multiplier(例如 0.90)进行相乘simdf_2

任何类型的建议都是可取的。

可重现的数据集

df_1

structure(list(id = 1:7, det_id = structure(c(5L, 4L, 6L, 7L, 
1L, 2L, 3L), .Label = c("FID00038 _ FSID013505 _ Taraxerol", 
"FID00087 _ FSID012362 _ beta-Sitosterol", "FID00094 _ FSID013269 _ Cholesterol", 
"FID00099 _ FSID012160 _ Riboflavine", "FID00119 _ FSID012160 _ Riboflavine", 
"FID00120 _ FSID009721 _ Lignin", "FID00120 _ FSID012362 _ beta-Sitosterol"
), class = "factor"), multiplyer = c(0.2, 0.3, 0.5, 0.2, 0.7, 
0.9, 0.05)), class = "data.frame", row.names = c(NA, -7L))

df_2

structure(list(Id_1 = structure(c(4L, 4L, 4L, 4L, 5L, 6L, 7L, 
8L, 8L, 1L, 3L, 2L), .Label = c("FID00038 _ FSID013505 _ Taraxerol", 
"FID00087 _ FSID012362 _ beta-Sitosterol", "FID00120 _ FSID001304 _ alpha1-Sitosterol", 
"ID00309", "ID00310", "ID00311", "ID00312", "ID00313"), class = "factor"), 
    Id_2 = structure(c(9L, 10L, 6L, 5L, 7L, 8L, 2L, 3L, 4L, 11L, 
    1L, 2L), .Label = c("FID00017 _ FSID004090 _ Atropine", "FID00038 _ FSID013505 _ Taraxerol", 
    "FID00087 _ FSID012362 _ beta-Sitosterol", "FID00094 _ FSID013269 _ Cholesterol", 
    "FID00099 _ FSID012160 _ Riboflavine", "FID00119 _ FSID012160 _ Riboflavine", 
    "FID00120 _ FSID009721 _ Lignin", "FID00120 _ FSID012362 _ beta-Sitosterol", 
    "ID00314", "ID00315", "ID00910"), class = "factor"), sim = c(0.55, 
    0.66, 0.97, 0.66, 0.55, 0.34, 0.44, 0.55, 0.23, 0, 1, 0.78
    ), new_ssp = structure(list(sim = c(NA, NA, 0.194, 0.198, 
    0.275, 0.068, 0.308, 0.495, 0.0115, NA, NA, 0.546)), class = "data.frame", row.names = c(NA, 
    -12L))), row.names = c(NA, -12L), class = "data.frame")

我认为您建议的代码中有一些小错别字(例如乘法器与乘法器),但我暂时忽略了这一点。尝试这样的事情,使用 lapply 循环遍历您要相乘的每个变量。得到结果集后,再取parallel maximum:

o <- lapply(df_2[c("Id_1","Id_2")], function(x) {
  df_1$multiplyer[match(x, df_1$det_id)] * df_2$sim 
})
o <- do.call(pmax, c(o, na.rm=TRUE))
o[is.na(o)] <- df_2$sim[is.na(o)]
o
#[1] 0.5500 0.6600 0.1940 0.1980 0.2750 0.0680 0.3080 0.4950 0.0115 0.0000 1.0000 0.7020