【问题标题】:Use extract and/or separate to isolate variable string from dataframe使用提取和/或分离将变量字符串与数据帧隔离开来
【发布时间】:2018-09-05 14:25:58
【问题描述】:

我浏览了以下关于使用正则表达式隔离字符串的页面:

Regular expression to extract text between square brackets

What is a non-capturing group? What does (?:) do?

Split data frame string column into multiple columns

我有一个包含蛋白质/基因标识符的数据框,在某些情况下,由于列表中有多个匹配项,因此存在两个或多个这些字符串(用逗号分隔)。在这种情况下,第一个字符串是最强的匹配,我不一定对保留其余的字符串感兴趣。它们代表来自推断证据的多个匹配,并且当它们无法轻易区分时,所有匹配都被放入列中。在这种情况下,我只对保留第一个感兴趣,因为该组可能具有相同类型的注释(即蛋白质类型、基因本体、类似功能等)如果我将多个条目分成更多行,那么看起来我有证据表明它们存在于我的数据集中,但在经验层面上我没有。

我的数据框:

                protein
1 sp|P50213|IDH3A_HUMAN
2  sp|Q9BZ95|NSD3_HUMAN
3  sp|Q92616|GCN1_HUMAN
4 sp|Q9NSY1|BMP2K_HUMAN
5  sp|O75643|U520_HUMAN
6 sp|O15357|SHIP2_HUMAN
523 sp|P10599|THIO_HUMAN,sp|THIO_HUMAN|
524 sp|Q96KB5|TOPK_HUMAN
525 sp|P12277|KCRB_HUMAN,sp|P17540|KCRS_HUMAN,sp|P12532|KCRU_HUMAN
526 sp|O00299|CLIC1_HUMAN
527 sp|P25940|CO5A3_HUMAN

我正在尝试创建的输出:

uniprot gene
P50213 IDH3A
Q9BZ95 NSD3
Q92616 GCN1
P12277 KCRB

我正在尝试使用 extractseparate 函数来执行此操作:

extract(df, protein, into = c("uniprot", "gene"), regex = c("sp|(.*?)|"," 
(.*?)_"), remove = FALSE)

结果:

Error: is_string(regex) is not TRUE

尝试separate 至少在多个步骤中将两者分开:

separate(df, protein, into = c("uniprot", "gene"), sep = "|", remove = 
FALSE)

结果:

Warning message:
Expected 2 pieces. Additional pieces discarded in 528 rows [1, 2, 3, 4, 5, 
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...]. 
                protein uniprot gene
1 sp|P50213|IDH3A_HUMAN            s
2  sp|Q9BZ95|NSD3_HUMAN            s
3  sp|Q92616|GCN1_HUMAN            s
4 sp|Q9NSY1|BMP2K_HUMAN            s
5  sp|O75643|U520_HUMAN            s
6 sp|O15357|SHIP2_HUMAN            s

在这种情况下使用正则表达式的最佳方式是什么?extractseparate 是解决此问题的最佳方式吗?任何建议将不胜感激。谢谢!

根据反馈进行更新:

df <- structure(list(protein = c("sp|P50213|IDH3A_HUMAN",  "sp|Q9BZ95|NSD3_HUMAN", 
                             "sp|Q92616|GCN1_HUMAN", "sp|Q9NSY1|BMP2K_HUMAN", "sp|O75643|U520_HUMAN", 
                             "sp|O15357|SHIP2_HUMAN", "sp|P10599|THIO_HUMAN,sp|THIO_HUMAN|", 
                             "sp|Q96KB5|TOPK_HUMAN",   "sp|P12277|KCRB_HUMAN,sp|P17540|KCRS_HUMAN,sp|P12532|KCRU_HUMAN", 
                             "sp|O00299|CLIC1_HUMAN")), class = "data.frame", row.names = c("1", 
                                                                                            "2", "3", "4", "5", "6", "523", "524", "525", "526"))
df1 <- separate(df, protein, into = "protein", sep = ",") 
#i'm only interested in the first match, because science

df2 <- extract(df1, protein, into = c("uniprot", "gene"), regex = "sp\\| 
([^|]+)\\|([^_]+)", remove = FALSE) 
#create new columns with uniprot code and gene id, no _HUMAN

#df2
#                 protein uniprot  gene
#1   sp|P50213|IDH3A_HUMAN  P50213 IDH3A
#2    sp|Q9BZ95|NSD3_HUMAN  Q9BZ95  NSD3
#3    sp|Q92616|GCN1_HUMAN  Q92616  GCN1
#4   sp|Q9NSY1|BMP2K_HUMAN  Q9NSY1 BMP2K
#5    sp|O75643|U520_HUMAN  O75643  U520
#6   sp|O15357|SHIP2_HUMAN  O15357 SHIP2
#523  sp|P10599|THIO_HUMAN  P10599  THIO
#524  sp|Q96KB5|TOPK_HUMAN  Q96KB5  TOPK
#525  sp|P12277|KCRB_HUMAN  P12277  KCRB
#526 sp|O00299|CLIC1_HUMAN  O00299 CLIC1

#and the answer using %>% pipes (this is what I aspire to)
df_filtered <- df %>%
separate(protein, into = "protein", sep = ",") %>%
extract(protein, into = c("uniprot", "gene"), regex = "sp\\|([^|]+)\\|([^_]+)") %>%
select(uniprot, gene)

#df_filtered
#    uniprot  gene
#1    P50213 IDH3A
#2    Q9BZ95  NSD3
#3    Q92616  GCN1
#4    Q9NSY1 BMP2K
#5    O75643  U520
#6    O15357 SHIP2
#523  P10599  THIO
#524  Q96KB5  TOPK
#525  P12277  KCRB
#526  O00299 CLIC1

【问题讨论】:

  • 第 523 行和第 525 行呢?这些看起来像多行组合,您希望它们如何分开?
  • 它们代表来自推断证据的多个匹配项,当它们无法轻松区分时,所有匹配项都被放入列中。在这种情况下,我只对保留第一个感兴趣,因为该组可能具有相同类型的注释(即蛋白质类型、基因本体、类似功能等)如果我将多个条目分成更多行,那么看起来我有证据表明它们存在于我的数据集中,但在经验层面上我没有。
  • 您应该将此评论添加到您的问题中并更新您想要的输出以反映这一点

标签: r tidyr stringr


【解决方案1】:

我们可以在extract 中将模式捕获为一个组((...))。在这里,我们在字符串的开头 (^) 匹配 sp,然后是 |(元字符 - 转义 \\),然后是一个或多个字符而不是作为一组捕获的 |,然后由| 和捕获的第二组字符

library(tidyverse)
extract(df, protein, into = c("uniprot", "gene"), 
     regex = "^sp\\|([^|]+)\\|([^|]+).*")

如果有多个 'sp' 实例,则使用 separate_rows 将行分隔为长格式,然后使用 extract

df %>%
   separate_rows(protein, sep=",") %>%
   extract(protein, into = c("uniprot", "gene"), 
    "^sp\\|([^|]+)\\|([^|]*).*")

有一个例子只有两组词。让它发挥作用

df %>%
  separate_rows(protein, sep=",") %>% 
  extract(protein, into = "gene", "([^|]*HUMAN)", remove = FALSE) %>% 
  mutate(uniprot = str_extract(protein, "(?<=sp\\|)[^_]+(?=\\|)")) %>%
  select(uniprot, gene)
#   uniprot        gene
#1   P50213 IDH3A_HUMAN
#2   Q9BZ95  NSD3_HUMAN
#3   Q92616  GCN1_HUMAN
#4   Q9NSY1 BMP2K_HUMAN
#5   O75643  U520_HUMAN
#6   O15357 SHIP2_HUMAN
#7   P10599  THIO_HUMAN
#8     <NA>  THIO_HUMAN
#9   Q96KB5  TOPK_HUMAN
#10  P12277  KCRB_HUMAN
#11  P17540  KCRS_HUMAN
#12  P12532  KCRU_HUMAN
#13  O00299 CLIC1_HUMAN

数据

df <- structure(list(protein = c("sp|P50213|IDH3A_HUMAN",  "sp|Q9BZ95|NSD3_HUMAN", 
   "sp|Q92616|GCN1_HUMAN", "sp|Q9NSY1|BMP2K_HUMAN", "sp|O75643|U520_HUMAN", 
  "sp|O15357|SHIP2_HUMAN", "sp|P10599|THIO_HUMAN,sp|THIO_HUMAN|", 
  "sp|Q96KB5|TOPK_HUMAN",   "sp|P12277|KCRB_HUMAN,sp|P17540|KCRS_HUMAN,sp|P12532|KCRU_HUMAN", 
  "sp|O00299|CLIC1_HUMAN")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "523", "524", "525", "526"))

【讨论】:

  • 现在提取函数隔离IDH3A_HUMAN 如果我只想要IDH3A 怎么办?我已经尝试过^sp\\|C[^|]+)\\|([^|]+)\\_,因为我希望所有内容都指向_,但是当我使用^sp\\|C[^|]+)\\|([^_HUMAN]+) 试图说“匹配| 之后的所有内容但_HUMAN "
  • @AdamRabalski 可以查看最后一段代码
  • 好的,我想我得到了这样的sp\\|([^|]+)\\|([^_]+),它说除了_ 之外的所有东西都正确吗? [^_]+ 的推断功能是否意味着“除了_ 之外的所有内容并停在那里”?我的输出不包括HUMAN,这就是我问的原因。很快就会用我的答案更新我的帖子。
  • @AdamRabalski 它暗示 sp 后跟 |(元字符 - 转义 \`), followed by one or more character that are not a |` ([^|]+)` 被捕获为组,然后是 | 和第二个捕获的组不是[的字符
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 2022-11-03
  • 1970-01-01
相关资源
最近更新 更多