替换 hapmap 数据集中的字符

替换 hapmap 数据集中的字符

我正在考虑使用 bash 代码来解决我的数据中的以下问题。

考虑到 hapmap 格式的以下数据集,我需要根据“等位基因”列的数据替换一些字符(在本例中为字母)。 “等位基因”列中的数据将是四个字母对的组合(A、G、C 和 T)。

rs#    alleles  chro    pos    ind1 ind2 ind3 ind4 ind5 ind6. . 
mar_1   G/T     1       2386806 G    T    T    G   K    T    
mar_2   T/G     1       2386848 T    G    T    K   T    K
mar_3   G/T     1       2387553 T    K    G    K   T    G
mar_4   G/A     1       2564608 G    G    G    N   R    A
mar_5   C/T     1       2564616 C    Y    C    Y   T    N
.
.

我想要得到的是一个遍历整行的代码(在第 1 行的情况下),当它找到字母“T”(“/”之后的字母)时,将其替换为字母“G”(之前的字母)当它找到字母“R”、“Y”、“S”、“W”、“K”或“M”时,将其替换为“T”(“/”之后的字母)。

换句话说,代码必须(在每一行中)找到与“/”之后的字母(在“等位基因”列中)匹配的所有字母,并将它们替换为与“/”之前的字母匹配的字母。并且,当它找到与以下之一匹配的字母时:(“R”、“Y”、“S”、“W”、“K”或“M”),它必须将其替换为匹配的字母与“/”后面的一个。

我想得到的输出是:

rs#    alleles  chro    pos    ind1 ind2 ind3 ind4 ind5 ind6. . 
mar_1   G/T     1       2386806 G    G    G    G   T    G    
mar_2   T/G     1       2386848 T    T    T    G   T    G
mar_3   G/T     1       2387553 G    T    G    T   G    G
mar_4   G/A     1       2564608 G    G    G    N   A    G
mar_5   C/T     1       2564616 C    T    C    T   C    N
.
.

注意:“N”表示缺失值,因此必须保留原样。

任何有关此问题的帮助将不胜感激。

答案1

perl

$ perl -F'\s+|/' -lape '
     s/^(\S+\s+){4}\K.*/$&=~s|$F[2]|$F[1]|gr/e;
     s/^(\S+\s+){4}\K.*/$&=~s|[RYSWKM]|$F[2]|gr/e
  ' ip.txt
rs#    alleles  chro    pos    ind1 ind2 ind3 ind4 ind5 ind6. . 
mar_1   G/T     1       2386806 G    G    G    G   T    G    
mar_2   T/G     1       2386848 T    T    T    G   T    G
mar_3   G/T     1       2387553 G    T    G    T   G    G
mar_4   G/A     1       2564608 G    G    G    N   A    G
mar_5   C/T     1       2564616 C    T    C    T   C    N
  • -F'\s+|/'按空格或/字符分割输入行,保存在@F数组中
  • ^(\S+\s+){4}\K.*将获取除前四列之外的所有列
  • $&=~s|$F[2]|$F[1]在匹配部分(前四列除外)执行另一次替换
    • $F[2]将包含之后的字符/并且$F[1]将包含之前的字符/
  • 修饰符r返回最终替换的字符串,并且e修饰符允许在替换部分使用 Perl 代码
  • 由于再次使用相同的模式,第二次替换也可以缩短为s//$&=~s|[RYSWKM]|$F[2]|gr/e
  • 命令开关-lape有关选项的解释

答案2

perl -F'/(\s+|\/)/' -lne '
   print @F[0..9], map { s/($F[4])|([RYSWKM])/$2?$F[4]:$F[2]/re } @F[10..$#F];
' hapmap.txt

sed -e '
   s/^\(\S\+\s\+\)\{4\}/&\n/                           # mark col-4

  :a
  s|^\(\S\+\s\+\(.\)/\(.\).*\n.*\)\3|\1\2|g;ta         # perform sub-1

  :b
  s|^\(\S\+\s\+\(.\)/\(.\).*\n.*\)[RYSWKM]|\1\3|g;tb   # perform sub-2

  s/\n//g                                              # throw away marker
' hap_map.txt

相关内容