2

I am trying to set up a script which will convert a codon sequence to another codon sequence depending on variants I find in my NGS data.

Currently, My script creates a tab-delimited output file, With 6 columns. Each column represents the following:

  • 1st: Genome position
  • 2nd: Nucleotide base
  • 3rd: Codon
  • 4th: Genome position order in the codon
  • 5th: SNP frequency
  • 6th: SNP Base

The output data looks like this:

2289     G       GTG    3        0.0346505      A

2478     G       ATG    2        0.0054087      C

Is it possible to set up a 7th column in the output file, which changes the nucleotide sequence of the codon depending on the number in column 4, to the SNP nucleotide (column 6)?

For example,

  • For genome position 2289:

The codon GTG would become GTA. The SNP nucleotide A replaces the 3rd nucleotide sequence in the codon, the codon sequence order is specified in column 4.

  • For genome Position 2478

The codon ATG would become ACG. The SNP nucleotide C replaces the 2nd nucleotide sequence in the codon.

Is it possible to use awk or sed to do this?

2
  • @JeffSchaller I reverted the edit because losing the output format makes it harder to determine the answer... Jan 2, 2018 at 22:42
  • Fair enough, @StephenKitt — it looked more readable to me, but I wasn’t trying to answer. Thank you!
    – Jeff Schaller
    Jan 2, 2018 at 22:49

5 Answers 5

1

It was so tempting to just answer "yes" to the question "is it possible to....".

Would something like this do?

awk '{l=substr($3,1,$4-1); r=substr($3,$4+1); print $0"\t"l $6 r}' genome > mutated
1

Perl solution:

perl -lane 'substr $n = $F[2], $F[3] - 1, 1, $F[5]; print join "\t", $_, $n' -- file
  • -n reads the input line by line
  • -l removes newlines from input and adds them to prints
  • -a splits each line on whitespace into the @F array
  • see substr for details
1

With some perl splitting and joining:

perl -alne '
  @c = split //, $F[2]; 
  splice @c, $F[3]-1, 1, $F[5]; 
  print join "\t", @F, join "", @c;
' data

Explanation:

- split 3rd column into character array @c
- replace the value indexed by the 4th column with that of the 6th
- stitch it all back together, delimited by tabs

Testing - given

$ cat data
2289    G       GTG     3       0.0346505       A
2478    G       ATG     2       0.0054087       C

then

$ perl -alne '
    @c = split //,$F[2]; splice @c,$F[3]-1,1,$F[5]; print join "\t",@F,join "",@c
  ' data
2289    G       GTG     3       0.0346505       A       GTA
2478    G       ATG     2       0.0054087       C       ACG
0

Taking care of allowable positions in the string:

awk -F"\t" '{printf $0 "\t"; if ($4 > 1) { printf substr($3, 1, $4 - 1) }; printf $6; if ($4 < length($3)) { printf substr($3, $4 + 1) }; printf "\n"}'

Or perhaps a bit more understandably:

awk -F"\t" 'BEGIN { OFS = FS } { if ($4 > 1) { mod = substr($3, 1, $4 - 1) }; mod = mod $6; if ($4 < length($3)) { mod = mod substr($3, $4 + 1) }; print $0, mod }'

And since substr doesn't appear to care all that much about bounds:

awk -F"\t" 'BEGIN { OFS = FS } { mod = substr($3, 1, $4 - 1) $6 substr($3, $4 + 1); print $0, mod }'
0
perl -plane 'substr($F[2],$F[3]-1,1)=$F[5]; $_.="\t$F[2]"' data
  • change F2 according to the question substr($F[2],$F[3]-1,1)=$F[5]
  • and concatenate it to the input line $_.="\t$F[2]"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .