-1

I am thinking to use a bash code to solve the following issue in my data.

Considering the bellow data set in hapmap format in which I need to replace some characters (letters in this case) based on the data of the column "alleles". Data in the column "alleles" will be a combination in pairs of four letters (A, G, C, and 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
.
.

What I want to get is a code that go through the entire row (in the case of row 1) and when it find a letter "T" (letter after the "/") replace it by a letter "G" (letter before the "/") and when it find either a letter "R", "Y", "S", "W", "K", or "M" replace it by "T" (letter after "/").

In other words the code has to find (in each row) all the letters that match with the letter after the "/" (in the column "alleles") and replace them by a letter that match with the letter before the "/". And, when it finds a letter that match with one of these: ("R","Y", "S", "W", "K", or "M") it has to replace it by a letter that match with the one after the "/".

The output I would like to get is:

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
.
.

Note: The "N" means a missing value, so it has to be kept such is it.

Any help with this issue will be greatly appreciate.

  • 3
    Please edit your question and show us your desired output. That way we can be sure that we've understood your requirements. I read your description twice (and I actually work in the field) and I don't understand exactly what you need. – terdon Apr 4 '17 at 16:28
  • I already edited my question, hopefully is clearer now. Thanks – Fersal Apr 5 '17 at 3:07
0

With 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+|/' split input line on white spaces or the / character, saved in @F array
  • ^(\S+\s+){4}\K.* will get all columns except the first four
  • $&=~s|$F[2]|$F[1] on the matched portion (columns except first four) perform another substitution
    • $F[2] will contain the character after / and $F[1] will contain the character before /
  • The r modifier returns the final substituted string and e modifier allows to use Perl code in replacement section
  • Since same pattern is used again, the second substitution can also be shortened to s//$&=~s|[RYSWKM]|$F[2]|gr/e
  • See command switches for explanation on -lape options
  • I am getting this error: Bad name after F 'at recode.pl line 2 Although I have to admit my knowledge of Perl is 0 – Fersal Apr 6 '17 at 14:12
  • not sure, may be copy paste error? try as one-liner.. perl -F'\s+|/' -lape 's/^(\S+\s+){4}\K.*/$&=~s|$F[2]|$F[1]|gr/e;s//$&=~s|[RYSWKM]|$F[2]|gr/e' ip.txt and what is your perl version? mine is v5.22.1 – Sundeep Apr 6 '17 at 14:24
  • One-liner works very well, great! My Perl version is v5.16.3 Just for curiosity, do you think my previous error was due to the version? Thanks – Fersal Apr 6 '17 at 14:52
  • no idea.. both work for me.. – Sundeep Apr 6 '17 at 15:01
0
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.