2016-07-12 2 views
0

Comment je transforme une colonne en ligne dans Terminal Linux? Mais plus complexe ... Voici un exemple de mes données:Comment transformer une colonne en ligne dans Terminal Linux? Mais plus complexe

SNP_Name  ID_Animal  Allele  Chr  Position 
rs01   215    AB   1   100 
rs02   215    AA   2   200 
rs03   215    BA   3   300 
rs04   215    AA   4   400 
rs01   300    AB   1   100 
rs02   300    BB   2   200 
rs03   300    AA   3   300 
rs04   300    AB   4   400 
rs01   666    BB   1   100 
rs02   666    AA   2   200 
rs03   666    AB   3   300 
rs04   666    AB   4   400 

Je veux transformer cela en ce qui suit:

SNP_Name  Chr  Position 215(ID_animal) 300(ID_Animal) 666(ID_Animal) 
rs01   1  100  AB    AB   BB 
rs02   2  200  AA    BB   AA 
rs03   3  300  BA    AA   AB 
rs04   4  400  AA    AB   AB 

La ligne ID_animal changement dans la colonne avec allèle respectif. Comment je fais ça? Mais je vais travailler avec 55 000 répétitions par ID_animal. Donc, je veux être seulement 55 000 rangées et (animal number + SNP_Name + Chr + Position) de la colonne.

Merci.

+0

Donc pour chaque SNP ('rs'-ID), vous voudriez lister les animaux ayant ce SNP et quel allèle ils ont. Tous les animaux sont-ils génotypés avec tous les «rs'-ID»? (c'est-à-dire que chaque 'ID_Animal' se produira exactement une fois pour chaque 'Nom_SNP'?) – Kusalananda

+0

Oui, tous les ID_animaux se produisent exactement une fois pour chaque SNP_Name. Savez-vous comment je peux faire? Je vous remercie. –

+0

Mais je dois avoir ID_animal en colonne, car j'utiliserai le paquet GenABEL dans R, pour calculer le déséquilibre de liaison du génome, donc l'entrée a besoin de cette structure. –

Répondre

1

Le problème ici est la quantité de données, et je ne veux pas donner une solution qui lit tout dans la mémoire et puis la sort. Pour ce faire, je voudrais analyser et sortir les données pour chaque SNP (numéro rs) à tour de rôle plutôt que pour chaque animal à son tour. Mais les données nous sont données dans le mauvais ordre (triées par animal). Donc, la première chose que nous devons faire est de trier les données par SNP (la première colonne). Je vais également supprimer la ligne d'en-tête en même temps qu'elle n'est pas nécessaire pour la transformation de données.

Je suppose que les données sont stockées dans le fichier data.in:

$ sed '1d' data.in | sort -o data.tmp 

Nous avons maintenant:

$ cat data.tmp 
rs01   215    AB   1   100 
rs01   300    AB   1   100 
rs01   666    BB   1   100 
rs02   215    AA   2   200 
rs02   300    BB   2   200 
rs02   666    AA   2   200 
rs03   215    BA   3   300 
rs03   300    AA   3   300 
rs03   666    AB   3   300 
rs04   215    AA   4   400 
rs04   300    AB   4   400 
rs04   666    AB   4   400 

Puis-je exécuter ce qui suit pour produire le résultat:

$ awk -f script.awk data.tmp >data.new 

Le script awk est assez long, il est donc logique de l'avoir dans son o fichier script WN plutôt que comme un "one-liner":

FNR == 1 { 
    # at first line of input 

    rsid  = $1; 
    chr   = $4; 
    pos   = $5; 

    c   = 0; 
    aid[c]  = $2; # animal ID 
    all[c++] = $3; # allele 

    do_header = 1; # output header when done parsing this SNP 

    next; 
} 

rsid == $1 { 
    # still reading animal ID/allele for this SNP 
    aid[c]  = $2; 
    all[c++] = $3; 
    next; 
} 

{ 
    if (do_header) { 
     # output header 

     printf("SNP_name\tChr\tPosition\t"); 
     for (c in aid) { 
      printf("%d\t", aid[c]); 
     } 
     printf("\n"); 

     do_header = 0; 
    } 

    # output line with data from previous SNP  
    printf("%s\t%d\t%d\t", rsid, chr, pos); 
    for (c in all) { 
     printf("%s\t", all[c]); 
    } 
    printf("\n"); 

    # store data for this SNP 
    rsid  = $1; 
    chr   = $4; 
    pos   = $5; 

    c   = 0; 
    aid[c]  = $2; 
    all[c++] = $3; 
} 

END { 
    # output line for last SNP 

    printf("%s\t%d\t%d\t", rsid, chr, pos); 
    for (c in all) { 
     printf("%s\t", all[c]); 
    } 
    printf("\n"); 
} 

Ceci produit le fichier délimité par des tabulations data.new avec le contenu suivant, pour l'entrée donnée:

SNP_name Chr Position 215 300 666 
rs01 1 100 AB AB BB 
rs02 2 200 AA BB AA 
rs03 3 300 BA AA AB 
rs04 4 400 AA AB AB 

NOTE: Ce nécessite que tous les animaux ont été génotypés pour exactement les mêmes SNP. Les mêmes ID d'animal doivent apparaître pour chaque SNP. Aucune exception.

+0

Merci beaucoup @kusalananda !!! –