正在分析中的数据

2024-04-28 13:23:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样的遗传学数据:

MUT1    G_->_A_(het)    44%_(96)___[45%_(49)_/_43%_(47)]    rs1799967_(Gene_file;_1000Genomes;_ClinVarVCF;_dbSNP,MutDB) c.4956G>A   1
MUT1    A_->_G_(homo)   99%_(297)___[99%_(151)_/_99%_(146)] rs206075_(Gene_file;_1000Genomes;_ClinVarVCF;_dbSNP)    c.4563A>G   1
MUT1    G_->_C_(homo)   100%_(259)___[100%_(132)_/_100%_(127)]  COSM4147689_(COSMIC),_COSM4147690_(COSMIC),_rs206076_(Gene_file;_1000Genomes;_ClinVar;_ClinVarVCF;_dbSNP)   c.6513G>C   2
MUT1    A_->_C_(het)    41%_(103)___[42%_(53)_/_40%_(50)]   COSM3753646_(COSMIC),_COSM147663_(COSMIC),_rs144848_(Gene_file;_1000Genomes;_ClinVarVCF;_dbSNP,MutDB)   c.1114A>C   5

我需要解析这些数据并只提取一些字段。在

所需输出为:

^{pr2}$

所以输出应该是-所有第一列列,从第二列到第二列只有het或hom,第三列是%,第五列应该只提取rs_数——这总是不同的位置和最后一列。在

注:我知道,关于人/人的信息总是在第二栏的最后一个栏位。而且%总是在第三列的第一个字段上。在

我的解决方案是:

awk -v OFS="\t" '{print $1,$5,$6,$9,$10,$11}' zkouska.csv | awk -v OFS="\t" 'NR>1{split($2,arr2,"_"); split($3,arr3,"_"); print $1,arr2[4],arr3[1],$4,$5,$6}' 

但输出是:

BRCA1   (het)   44% rs1799967_(Gene_file;_1000Genomes;_ClinVarVCF;_dbSNP,MutDB) c.4956G>A   1
BRCA1   (homo)  99% rs206075_(Gene_file;_1000Genomes;_ClinVarVCF;_dbSNP)    c.4563A>G   1
BRCA1   (homo)  100%    COSM4147689_(COSMIC),_COSM4147690_(COSMIC),_rs206076_(Gene_file;_1000Genomes;_ClinVar;_ClinVarVCF;_dbSNP)   c.6513G>C   2
BRCA1   (het)   41% COSM3753646_(COSMIC),_COSM147663_(COSMIC),_rs144848_(Gene_file;_1000Genomes;_ClinVarVCF;_dbSNP,MutDB)   c.1114A>C   5
BRCA1   (homo)  100%    COSM148277_(COSMIC),_COSM3755561_(COSMIC),_rs16942_(Gene_file;_1000Genomes;_ClinVarVCF;_dbSNP)  c.3548A>G   5

从第五列中提取rs仍然存在问题。删除第二个字段中的引号。输入和输出应该用制表符分开。解决方案不可能只有awk。


Tags: 数据filegenecosmicawkhomohetdbsnp
3条回答
$ perl -lne 'print join "\t", /^(\S+)/,/^[^(]+\(\K([^)]+)/,/^[^)]+\)\s+\K(\d+%)/,/(rs\d+)/,/(\S+\s+\S+)\s*$/' file
MUT1    het 44% rs1799967   c.4956G>A   1
MUT1    homo    99% rs206075    c.4563A>G   1
MUT1    homo    100%    rs206076    c.6513G>C   2
MUT1    het 41% rs144848    c.1114A>C   5
  • /^(\S+)/从行首提取非空白字符
  • /^[^(]+\(\K([^)]+)/提取第一个()之间的字符
  • /^[^)]+\)\s+\K(\d+%)/提取行中第一个)后的第一个匹配数字,后跟%
  • /(rs\d+)/提取{},后跟数字
  • /(\S+\s+\S+)\s*$/提取最后两列


另一种方法是分别处理每个字段,类似于bash和{}解决方案

^{pr2}$

使用gsubmatch的组合可能是一种方法,下面是一个可移植的示例:

解析.awk

{
  gsub(/^[^(]+\(|\)/, "", $2)
  gsub(/_.*/, "", $3)
  match($4, /rs[0-9]+/)
  print $1, $2, $3, substr($4, RSTART, RLENGTH), $5, $6
}

这样运行:

^{pr2}$

输出:

MUT1    het     44%     rs1799967   c.4956G>A   1
MUT1    homo    99%     rs206075    c.4563A>G   1
MUT1    homo    100%    rs206076    c.6513G>C   2
MUT1    het     41%     rs144848    c.1114A>C   5

我为您的需求发布了一个纯粹的bash逻辑。在

#!/bin/bash

while read col1 col2 col3 col4 col5 col6
do
    subcol2="${col2#*(}";subcol2=${subcol2%)*}                             # Extracting string within the braces '()' using parameter-expansion              
    [[ $col4 =~ .*rs([[:digit:]]+).* ]] && subcol4="${BASH_REMATCH[1]}"    # RegEx in bash to extract number following the 'rs' string
    printf "%s %s %s %s %s %s\n" "$col1" "$subcol2" "${col3%%_*}" "rs$subcol4" "$col5" "$col6"
done <file

在运行脚本时,生成的结果为

^{pr2}$

注意:解决方案在较大文件上的执行速度可能较慢。我只在你的样本文件上测试过这个。在

相关问题 更多 >