删除第三列中的所有内容,但只保留特定文本

删除第三列中的所有内容,但只保留特定文本

我有一个包含三列的数据集:

https://drive.google.com/file/d/1gtCssfAXHxRjGfX8uTAaimGPWCA2cnci/view?usp=sharing

以下是前几行:

ID  transcript_id   go_description
MA_10000213g0010    MA_10000213g0010    
MA_10000405g0010    MA_10000405g0010    GO:0006468-protein phosphorylation;GO:0030246-carbohydrate binding;GO:0005524-ATP binding;GO:0004672-protein kinase activity
MA_1000049g0010 MA_1000049g0010 
MA_10000516g0010    MA_10000516g0010    GO:0005515-protein binding
MA_10001015g0010    MA_10001015g0010    
MA_10001337g0010    MA_10001337g0010    
MA_10001425g0010    MA_10001425g0010    
MA_10001478g0010    MA_10001478g0010    
MA_10001558g0010    MA_10001558g0010    
MA_10001g0010   MA_10001g0010   
MA_10002030g0010    MA_10002030g0010    GO:0005737-cytoplasm;GO:0000184-nuclear-transcribed mRNA catabolic process, nonsense-mediated decay;GO:0004386-helicase activity;GO:0008270-zinc ion binding;GO:0003677-DNA binding;GO:0005524-ATP binding
MA_10002157g0010    MA_10002157g0010    GO:0006468-protein phosphorylation;GO:0005524-ATP binding;GO:0004672-protein kinase activity
MA_10002549g0010    MA_10002549g0010    
MA_10002583g0010    MA_10002583g0010    GO:0008168-methyltransferase activity
MA_10002614g0010    MA_10002614g0010    
MA_10002643g0010    MA_10002643g0010    GO:0055114-oxidation-reduction process

在第三列中,我想删除所有文本,只保留GO:xxxxxxx每个术语应以逗号分隔的位置。例如:

GO:0006468, GO:0030246

前两列应保持不变。我怎样才能做到这一点?

答案1

假设您的数据是制表符分隔的,您可以这样做:

perl -F'\t' -lane '
  $F[2] = join(",", $F[2]=~/GO:\d+/g); 
  print join "\t",@F
' gene_table_Go\ -\ gene_table_Go.tsv > fixed.tsv

make-aperl作用类似于awknd 将每个输入行拆分到@F由 给定的字符上的数组中-F。在这里,我传递了一个选项卡(如果还没有,您可以随时将文件保存为制表符分隔的文件)。接下来,我将第三个字段 设定$F[2]为将GO:现有第三个字段中所有出现的 后跟数字连接起来的结果,换句话说,只保留 GO 术语而不保留其他任何内容。然后,我打印@F由制表符连接的数组。

这是相同基本思想的更浓缩版本:

perl -F'\t' -lane '
 $,="\t"; 
 print @F[0..1], join(",",$F[2]=~/GO:\d+/g);
' gene_table_Go\ -\ gene_table_Go.tsv 

两个示例产生相同的输出:

$ perl -F'\t' -lane '$,="\t"; print @F[0,1], join(",",$F[2]=~/GO:\d+/g);' gene_table_Go\ -\ gene_table_Go.tsv | head
ID  transcript_id   
MA_10000213g0010    MA_10000213g0010    
MA_10000405g0010    MA_10000405g0010    GO:0006468,GO:0030246,GO:0005524,GO:0004672
MA_1000049g0010 MA_1000049g0010 
MA_10000516g0010    MA_10000516g0010    GO:0005515
MA_10001015g0010    MA_10001015g0010    
MA_10001337g0010    MA_10001337g0010    
MA_10001425g0010    MA_10001425g0010    
MA_10001478g0010    MA_10001478g0010    
MA_10001558g0010    MA_10001558g0010    

为了保持标题完整,因为它实际上与GO:\d+模式不匹配,您可以这样做:

$ perl -F'\t' -lane '$,="\t"; print $. == 1 ? @F : @F[0,1], join(",",$F[2]=~/GO:\d+/g);' gene_table_Go\ -\ gene_table_Go.tsv | head
ID  transcript_id   go_description
MA_10000213g0010    MA_10000213g0010    
MA_10000405g0010    MA_10000405g0010    GO:0006468,GO:0030246,GO:0005524,GO:0004672
MA_1000049g0010 MA_1000049g0010 
MA_10000516g0010    MA_10000516g0010    GO:0005515
MA_10001015g0010    MA_10001015g0010    
MA_10001337g0010    MA_10001337g0010    
MA_10001425g0010    MA_10001425g0010    
MA_10001478g0010    MA_10001478g0010    
MA_10001558g0010    MA_10001558g0010    

答案2

AWK:

$ awk '
     BEGIN{FS=OFS="\t"}
     {
  while(match($3,/GO:[0-9]+/)) 
     {
  col= sprintf("%s",((col) ? col ",": "")substr($3,RSTART,RLENGTH));  
  $3= substr($3,RSTART+RLENGTH)
     }
     }
  col{ $3=col; col=""}
  1'

答案3

使用(以前称为 Perl_6)

假设\t制表符作为列分隔符:

~$ raku -ne 'BEGIN put get;   \
             my @a = .split(:skip-empty, / \t /, 3);   \
             @a[2] = (@a[2] // "").comb(/ GO\: \d+ /).join(",");   \
             @a.join("\t").trim-trailing.put;'   file

这是用 Raku(Perl 编程语言家族的成员)编写的答案。逐行进行:

  1. BEGIN标题行的语句(put如果标题行\t像正文行一样用制表符分隔,则可以省略)。

  2. 正文行(行)可以拆分\t并保存到@a数组中。请注意,可能(但有风险)分割\s**4ie 四个连续的空白字符,甚至\h**4(四个连续的空白字符)水平的空白字符),如果第三列不包含该模式。但同样,这是有风险的。

  3. 第三列(即@a[2])被替换为@a[2]comb针对正则表达式 的一个或多个匹配项进行编辑(即正选)的列文本GO\: \d+。认为comb是相反的split(这是破坏性的)。然后用逗号将选定的GO-ID 连接起来。

  4. 最后,这些split列在选项卡join上重新组合在一起\t,然后输出put

输入示例:

ID  transcript_id   go_description
MA_10000213g0010    MA_10000213g0010
MA_10000405g0010    MA_10000405g0010    GO:0006468-protein phosphorylation;GO:0030246-carbohydrate binding;GO:0005524-ATP binding;GO:0004672-protein kinase activity
MA_1000049g0010 MA_1000049g0010
MA_10000516g0010    MA_10000516g0010    GO:0005515-protein binding
MA_10001015g0010    MA_10001015g0010
MA_10001337g0010    MA_10001337g0010
MA_10001425g0010    MA_10001425g0010
MA_10001478g0010    MA_10001478g0010
MA_10001558g0010    MA_10001558g0010
MA_10001g0010   MA_10001g0010
MA_10002030g0010    MA_10002030g0010    GO:0005737-cytoplasm;GO:0000184-nuclear-transcribed mRNA catabolic process, nonsense-mediated decay;GO:0004386-helicase activity;GO:0008270-zinc ion binding;GO:0003677-DNA binding;GO:0005524-ATP binding
MA_10002157g0010    MA_10002157g0010    GO:0006468-protein phosphorylation;GO:0005524-ATP binding;GO:0004672-protein kinase activity
MA_10002549g0010    MA_10002549g0010
MA_10002583g0010    MA_10002583g0010    GO:0008168-methyltransferase activity
MA_10002614g0010    MA_10002614g0010
MA_10002643g0010    MA_10002643g0010    GO:0055114-oxidation-reduction process

示例输出:

ID  transcript_id   go_description
MA_10000213g0010    MA_10000213g0010
MA_10000405g0010    MA_10000405g0010    GO:0006468,GO:0030246,GO:0005524,GO:0004672
MA_1000049g0010 MA_1000049g0010
MA_10000516g0010    MA_10000516g0010    GO:0005515
MA_10001015g0010    MA_10001015g0010
MA_10001337g0010    MA_10001337g0010
MA_10001425g0010    MA_10001425g0010
MA_10001478g0010    MA_10001478g0010
MA_10001558g0010    MA_10001558g0010
MA_10001g0010   MA_10001g0010
MA_10002030g0010    MA_10002030g0010    GO:0005737,GO:0000184,GO:0004386,GO:0008270,GO:0003677,GO:0005524
MA_10002157g0010    MA_10002157g0010    GO:0006468,GO:0005524,GO:0004672
MA_10002549g0010    MA_10002549g0010
MA_10002583g0010    MA_10002583g0010    GO:0008168
MA_10002614g0010    MA_10002614g0010
MA_10002643g0010    MA_10002643g0010    GO:0055114

https://docs.raku.org
https://raku.org

答案4

你可以考虑使用磨坊主,它内置了对 TSV 文件的支持 - 例如

  • $go_description将字段拆分;为数组
  • GO:nnnnnn应用正则表达式从数组的每个元素中提取子字符串
  • 将结果连接回一个,单独的字符串
  • 将结果分配回$go_description

所以

mlr --tsv put '
  $go_description = joinv(
    apply(splitax($go_description,";"),func(e) {return regextract(e,"GO:[[:digit:]]+")}),
    ","
  )
' gene_table_Go.tsv

相关内容