3

I have a file with genotype data. The second column has both alleles for a particular genetic variant concatenated, as below.

rs969931    CA  1.000   2.000   2.000   2.000   2.000   2.000   1.000   1.000
rs2745406   CT  0.000   2.000   2.000   1.000   1.000   2.000   1.000   1.000
rs6939431   AG  0.000   0.000   0.000   0.000   0.000   0.000   1.000   0.000
rs1233427   AG  1.000   2.000   2.000   2.000   2.000   1.000   1.000   1.000
rs1233426   AG  1.000   2.000   2.000   2.000   2.000   1.000   1.000   1.000
rs1233425   GC  1.000   1.999   1.999   2.000   2.000   2.000   1.000   1.000
rs362546    GA  1.000   2.000   2.000   2.000   2.000   1.000   1.000   1.000
rs909968    AG  0.000   2.000   2.000   1.000   1.000   1.000   1.000   1.000
rs909967    GA  1.000   2.000   2.000   2.000   2.000   2.000   1.000   1.000
rs886381    AG  0.000   0.000   0.000   0.000   0.000   0.000   0.000   1.000

I need to create a new file with the alleles as two separate columns, i.e. splitting the second column into two columns. Desired output below. Is there a way to specify multiple field separators in awk to achieve this?

rs969931    C A  1.000  2.000   2.000   2.000   2.000   2.000   1.000   1.000
rs2745406   C T  0.000  2.000   2.000   1.000   1.000   2.000   1.000   1.000
rs6939431   A G  0.000  0.000   0.000   0.000   0.000   0.000   1.000   0.000
rs1233427   A G  1.000  2.000   2.000   2.000   2.000   1.000   1.000   1.000
rs1233426   A G  1.000  2.000   2.000   2.000   2.000   1.000   1.000   1.000
rs1233425   G C  1.000  1.999   1.999   2.000   2.000   2.000   1.000   1.000
rs362546    G A  1.000  2.000   2.000   2.000   2.000   1.000   1.000   1.000
rs909968    A G  0.000  2.000   2.000   1.000   1.000   1.000   1.000   1.000
rs909967    G A  1.000  2.000   2.000   2.000   2.000   2.000   1.000   1.000
rs886381    A G  0.000  0.000   0.000   0.000   0.000   0.000   0.000   1.000
4

You can do it using the sub function in awk:

awk 'sub(/./,"& ",$2)1;' file

If you want tab-separated output, you can use:

awk -v OFS="\t" 'sub(/./,"&\t",$2)1;' file

Or in a variety of other tools:

  • Perl

    perl -alne '$F[1]=~s/./$& /; print "@F"' file
    

    Or, for tab-separated output:

    perl -alne '$F[1]=~s/./$&\t/; print join "\t",@F' file
    
  • GNU sed

    sed -r 's/\S+\s+\S/& /' file
    
  • Other sed

    sed  's/^[[:alnum:]]*[[:blank:]]*./& /' file
    
  • Shell

    while read -r snp nt rest; do 
        printf "%s\t%s\t%s\t%s\n" "$snp" "${nt:0:1}" "${nt:0:1}" "$rest"
    done < file
    
  • For such input fomat sed 's/[[:upper:]]/& /' or sed 's/ [A-Z]/& /'is enough, but much easy seems to use cut : cut -c-13,14- --output-delimiter=" " – Costas Nov 30 '14 at 21:10
  • @Costas you are assuming that the 1st column can never have a capital letter, and that the delimiter is a space. The cut approach is neat but less robust since even a change in whitespace will break it. Still, why don't you post these as answers? If the OP's data are indeed as simple as the example, they could be helpful. If you just leave them as a comment to my answer, I'm the only one who gets a notification about them and the only one to read it. Comments should be used to comment on the answer not to provide alternative answers. – terdon Dec 1 '14 at 12:54
  • I suppose that your answer is nice but I'd like to offer you some additional variant to put in variety other tool. The my offer is not enough for separate answer but can amplify yours (if you accept it) – Costas Dec 1 '14 at 13:17
  • @Costas it would be much better as a separate answer. It's a very different approach and is less robust to changes in the input as I said in my previous comment. As a general rule though, it's better to post answers with different approaches instead of giving them in comments. That way you can expand them, explain how they work and where they fail. – terdon Dec 1 '14 at 13:21
1

Use gsub in awk:

awk 'gsub(""," ",$2)1' file

Result:

rs969931  C A  1.000 2.000 2.000 2.000 2.000 2.000 1.000 1.000
rs2745406  C T  0.000 2.000 2.000 1.000 1.000 2.000 1.000 1.000
rs6939431  A G  0.000 0.000 0.000 0.000 0.000 0.000 1.000 0.000
rs1233427  A G  1.000 2.000 2.000 2.000 2.000 1.000 1.000 1.000
rs1233426  A G  1.000 2.000 2.000 2.000 2.000 1.000 1.000 1.000
rs1233425  G C  1.000 1.999 1.999 2.000 2.000 2.000 1.000 1.000
rs362546  G A  1.000 2.000 2.000 2.000 2.000 1.000 1.000 1.000
rs909968  A G  0.000 2.000 2.000 1.000 1.000 1.000 1.000 1.000
rs909967  G A  1.000 2.000 2.000 2.000 2.000 2.000 1.000 1.000
rs886381  A G  0.000 0.000 0.000 0.000 0.000 0.000 0.000 1.000
  • Why you put 1 in your script? It is not print synonym. You have one pattern already so there is no need to put other. – Costas Nov 30 '14 at 21:21

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.