匹配不同数据框中列之间的值

时间:2021-07-22 22:59:47

标签: r dataframe

所以我有两个包含“;”的数据框分开的 ID。我想查看 df2$Protein.IDs 中的哪些 ID 在 df1$subunits.UniProt.IDs. 中,理想情况下将匹配的 ID 作为列表返回。 我不确定如何解决这个问题,因为我在之前的问题中没有遇到任何问题。 我正在尝试使用 strsplit 将每个条目的 ID 分开,然后搜索每个条目的匹配项,目的是通过 for 循环遍历 df,但我对如何使其结合起来有点困惑。

df1 <- structure(list(ComplexName = c("Oligosaccharyltransferase complex (Stt3B variant)", 
"TRF1-TIN2 complex", "TRF1 telomere length regulation complex", 
"Rap1 complex", "TRF2-Rap1 complex III", "TRF-Rap1 complex I, 2MD"
), Organism = c("Mouse", "Mouse", "Mouse", "Mouse", "Mouse", 
"Mouse"), subunits.UniProt.IDs. = c("Q91YQ5;Q9DBG6;O54734;P61804;Q8BTV1;Q3TDQ1;Q9CQY5", 
"P70371;Q5EE38;Q9QXG9;Q91WC1", "Q6PFX9;P70371;Q9QXG9", "P70371;O35144;P70388;Q5EE38;Q9QXG9;Q91WC1;Q91VL8", 
"O35144;Q91VL8", "Q6PFX9;P70371;O35144;Q9QXG9;Q91WC1;Q91VL8")), row.names = 881:886, class = "data.frame")
df2 <- structure(list(Protein.IDs = c("E9QN37;A1L314", "A2A6U3;Q80UG5-2;Q80UG5-3;Q80UG5;A2A6U5;A8Y5D3", 
"A2A7A7;Q8CFX1;A2A7A8", "A6PW84;A2A7Q5;Q3V1T4-3;Q3V1T4", "A2ACG7;Q9DBG6", 
"F6TBV1;F6WHL0;A2ADH1;Q9CQY5-2;Q9CQY5-3;Q9CQY5", "A2AEM2;Q99LI2", 
"A2AFS0;Q8C483;P26638;A2AFS1", "A2AFW6;Q9D050;Q791V5;D6RCZ1", 
"Q3UB58;Q3UNJ0;A2AIN5;Q3UZ35;P21855", "A2AIW9;Q9DC61", "A2AL36;E9Q9E7;A2AS42;F6QP53;A2AL36-2", 
"A2AL50;Q8C0I1;H3BKN2;A2AL49;H3BIY5", "Q8CBM2;A2AL85;Q8BSY0", 
"A2AMH3;A2AMH5;A2AMH4;Q6X893;Q6X893-2;A2AMH8", "A2AMW0;P47757-2;A2AMV7;P47757;F6QJN8;F6YHZ8;F7CAZ6", 
"Q3U8S1;A2APM5;A2APM3;A2APM4;E9QKM8;Q80X37;A2APM1;A2APM2;P15379-2;P15379-3;P15379-6;P15379-11;P15379-5;P15379-10;P15379-9;P15379-4;P15379-8;P15379-7;P15379;P15379-12;P15379-13", 
"A2AR26;Q3UDF0;A2AR27", "E9Q8N1;E9Q8K5;A2ASS6;A2ASS6-2;A2AT70;F7CR78", 
"A2AUR7;Q9D031;Q01730"), Gene.names = c("Mpeg1", "Sep-09", "H6pd", 
"P3h1;Lepre1", "Rpn2", "Magt1", "Clcc1", "Sars", "Mtch2", "Cd72", 
"Pmpca", "Cntrl", "Agps", "Asph", "Slc44a1", "Capzb", "Cd44", 
"Slc2a6", "Ttn", "Rsu1")), row.names = c(NA, 20L), class = "data.frame")

谢谢!

2 个答案:

答案 0 :(得分:4)

假设该列添加到'df2'中,我们可以使用strsplit中的base R来拆分数据集中的两个相关列,使用intersect找到其中的公共元素list

的每个元素
un1 <- unique(unlist(strsplit(df1$subunits.UniProt.IDs., ";")))
df2$Common <- lapply(strsplit(df2$Protein.IDs, ";"), intersect, un1)

答案 1 :(得分:4)

您可以使用 dplyrtidyrstringr(或仅使用 tidyverse):

library(dplyr)
library(tidyr)
library(stringr)

df2 %>% 
  mutate(Protein = str_split(Protein.IDs, ";")) %>% 
  unnest(Protein) %>% 
  inner_join(df1 %>% 
              mutate(Protein = str_split(subunits.UniProt.IDs., ";")) %>% 
              unnest(Protein), by="Protein")

哪个返回

# A tibble: 2 x 6
  Protein.IDs                Gene.names Protein ComplexName                Organism subunits.UniProt.IDs.        
  <chr>                      <chr>      <chr>   <chr>                      <chr>    <chr>                        
1 A2ACG7;Q9DBG6              Rpn2       Q9DBG6  Oligosaccharyltransferase~ Mouse    Q91YQ5;Q9DBG6;O54734;P61804;~
2 F6TBV1;F6WHL0;A2ADH1;Q9CQ~ Magt1      Q9CQY5  Oligosaccharyltransferase~ Mouse    Q91YQ5;Q9DBG6;O54734;P61804;~

我们在 Protein.IDs 处拆分了 subunits.UniProt.IDs. / ;,并通过结果列内部连接了两个表。

由于 df1df2 的转换基本相同,您可以将其包装成一个函数。如果您必须处理多个 data.frames,这很有用:

split_function <- function(df, column, new_col) {
  df %>% 
    mutate({{new_col}} := str_split({{column}}, ";")) %>% 
    unnest({{new_col}})
}

inner_join(split_function(df1, subunits.UniProt.IDs., Protein), 
           split_function(df2, Protein.IDs, Protein),
           by = "Protein")