Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
972 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  Extraire des donnees de deux tableaux

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Extraire des donnees de deux tableaux

n°2170351
cmyriam
Posté le 09-01-2013 à 09:55:38  profilanswer
 

Bonjour,
 
Je viens juste de commencer Perl et j'aurai besoin de votre aide.
J'ai 2 tableaux, l'un avec une colonne contenant une liste de genes de la forme: FBgn0025
                                                                                                           FBgn0036
                                                                                                           FBgn0059
                                                                                                           ............
Dans mon deuxieme tableau, j'ai aussi une colonne avec une liste de genes dont certains sont les meme que ceux du tableau precedent et dans une deuxieme colonne, j'ai des informations sur chaque gene.
Ce tableau 2 est de cette forme: FBgn0045  Info
                                          FBgn0036  Info
                                          FBgn0089  Info
                                          ............   ....
Ce que je voudrais, c'est recuperer les infos du tableau 2 mais seulement pour les genes du tableau 1.
en gros je voudrais en fichiers de sortie, un tableaux avec ma liste de genes du tableau 1 et les infos sur ces genes.
 
J'ai essaye different script sans jamais arrive a un resultat.
Voila le dernier script que j'ai fait:
 
use v5.10.1;  
 
open FILEIN, "< tableaux2.txt" or die "Input file open failed: $!";
 
while(defined($l=<FILEIN> )){  
  chomp $l;  
  @a = split /\t/,$l;  
  $transtogene{$a[0]} = $a[1];  
}
close FILEIN;  
 
 
open FILEIN, "< tableaux1.txt" or die "Input file open failed: $!";
 
while(defined($l=<FILEIN> )){  
  chomp $l;  
  ($FBg,$count) = split /\t/,$l;  
  $FBgn = $transtogene{$FBg};  
  $genecount{$FBgn} += $count;  
}
close FILEIN;    
 
 
open FILEOUT, "> tableaux3.txt" or die "Output file open failed: $!";
@k = keys %genecount;  
@k = sort @k;  
foreach $e (@k){
  say FILEOUT "$e\t$genecount{$e}";
}
close FILEOUT;

 
Toute aide ou suggestions me serait utile.  
Merci.

mood
Publicité
Posté le 09-01-2013 à 09:55:38  profilanswer
 

n°2170447
gilou
Modérateur
Modzilla
Posté le 09-01-2013 à 14:27:23  profilanswer
 

Bonjour, c'est tout bête, et vous y étiez presque à mon avis:
Vous créez un hash, qui va avoir pour clé le nom ('FBgn0025' par exemple) et pour valeur l'info.
Vous lisez le premier fichier et créez une entrée dans le hash pour chaque ligne avec une valeur bidon pour l'info ('' par exemple)
Vous lisez le second fichier, et pour chaque ligne si le hash a une entrée pour la clé (tester avec exists) vous associez a cette entrée l'info comme valeur.
 
Si ces infos ne vous suffisent pas, je vous écrirais le code, mais à vue de nez ce serait, en partant de votre code (qui manifestement fait d'autres choses)
 
open FILEIN, "< tableaux1.txt" or die "Input file open failed: $!";  
 
while(defined($l=<FILEIN> )){  
  chomp $l;  
  ($FBg, $count) = split /\t/,$l;  
  $transtogene{$FBg} = '';  
}  
close FILEIN;    
 
open FILEIN, "< tableaux2.txt" or die "Input file open failed: $!";  
 
while(defined($l=<FILEIN> )){  
  chomp $l;  
  @a = split /\t/,$l;  
  $transtogene{$a[0]} = $a[1] if exists $transtogene{$a[0]};  
}  
close FILEIN;    
 
open FILEOUT, "> tableaux3.txt" or die "Output file open failed: $!";  
@k = keys %transtogene;  
@k = sort @k;  
foreach $e (@k){  
  say FILEOUT "$e\t$transtogene{$e}";  
}  
close FILEOUT;  
 
A+,


Message édité par gilou le 09-01-2013 à 14:44:32

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2170465
cmyriam
Posté le 09-01-2013 à 15:32:44  profilanswer
 

Merci beucoup pour les infos.
Le code marche tres bien.

n°2170470
gilou
Modérateur
Modzilla
Posté le 09-01-2013 à 15:48:00  profilanswer
 

Chouette!  
Attention au cas des gènes présents dans le premier et pas le second, que j'ai vu en faisant un petit test (je ne connais pas vos données, donc ce n'est peut être pas possible avec).  
Si j'avais eu à l'écrire, j'aurais écrit ceci:
 

Code :
  1. #!/usr/bin/perl
  2. use v5.10.1;
  3. # code propre
  4. use strict;
  5. use warnings;
  6. use autodie;
  7.  
  8. my ($input1, $input2, $output) = ('tg1.txt', 'tg2.txt', 'tg3.txt');
  9. my $fh;
  10. my %data;
  11. # lecture du premier fichier et recupération des infos
  12. open $fh, "< $input1";
  13. foreach (<$fh> ) {
  14.  chomp;
  15.  undef $data{(split(/\t/, $_))[0]} if (/\t/);
  16. }
  17. close $fh;
  18. # lecture du second fichier et recupération des infos
  19. # pour les entrées présentes dans le premier
  20. open $fh, "< $input2";
  21. foreach (<$fh> ) {
  22.  chomp;
  23.  if (/\t/) {
  24.    my ($key, $val) = (split(/\t/, $_))[0,1];
  25.    $data{$key} = $val if exists $data{$key};
  26.  }
  27. }
  28. close $fh;
  29. #suppression des entrées présentes dans le premier seulement
  30. foreach (keys %data) {
  31.  delete $data{$_} unless defined $data{$_};
  32. }
  33. # écriture du fichier de sortie
  34. open $fh, "> $output";
  35. foreach (sort(keys %data)) {
  36.  say $fh "$_\t$data{$_}";
  37. }
  38. close $fh;


En lecture, plutôt que regarder si les lignes sont defined (je comprends d'ailleurs pas trop l'emploi du test avec defined dans votre code), je ne fais une action que si un \t est repéré dans la ligne, ça m'a paru plus efficace au vu de vos lignes utiles.
undef $data{'key'} est un idiome qui force la création de la clé 'key' pour pouvoir mettre sa valeur associée à undef, ce qu'on peut tester ensuite avec defined.
A+,


Message édité par gilou le 09-01-2013 à 16:22:50

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2170771
cmyriam
Posté le 11-01-2013 à 17:11:53  profilanswer
 

Merci encore pour la derniere fois.
 
Helas, j'ai encore un probleme.
J'ai toujours 2 tableaux (2 fichiers excels), mais cette fois je cherche les genes se situant entre deux coordonnees.
Voila a quoi ressemble mon premier tableau:   Start    End      Middle
                                                             1000    1200     1100  
                                                             2200    3000     2600
                                                             5000    6000     5000
 
Et voila a quoi ressemble le deuxieme tableau:   Start    End      Genes
                                                               980      1100      FBgn00026  
                                                               2500    5000      FBgn0027
                                                               3060    4500      FBgn0028
                                                               5200    7000      FBgn0029
                                                               5400    5800      FBgn0030
                                                               6050    8000      FBgn00036
 
En gros je voudrais un fichier de sortie avec seulement les genes et leur coordonnee correspondant seulement aux coordonnees du tableau 1. Ou autrement, les genes se situant sur les coordonnees de mon tableau 1.
C'est a dire si je reprend mon exemple:            Start    End      Genes
                                                               980      1100      FBgn00026  
                                                               2500    5000      FBgn0027
                                                               
                                                               5200    7000      FBgn0029
                                                               5400    5800      FBgn0030
 
J'avoue que je n'arrive pas a faire de script Perl pour faire cela.  
Si quelqu'un avait une solution, cela m'aiderai beaucoup.
Merci d'avance.
                                                             

n°2170790
gilou
Modérateur
Modzilla
Posté le 11-01-2013 à 21:11:28  profilanswer
 

Bonjour,
Je crains de ne pas bien avoir compris sur quel critères vous éliminez la ligne contenant FBgn0029.
Pourriez vous préciser ceci. Merci.
 
Parce que à la base, le code final va probablement ressembler à ceci:

Code :
  1. #!/usr/bin/perl
  2. use v5.10.1;
  3. # code propre
  4. use strict;
  5. use warnings;
  6. use autodie;
  7.  
  8. use Data::Dumper;
  9.  
  10. my ($input1, $input2, $output) = ('gt1.txt', 'gt2.txt', 'gt3.txt');
  11. my ($fh1, $fh2);
  12. my @ranges;
  13.  
  14. open $fh1, "< $input1";
  15. while (<$fh1> ) {
  16.  next if $. == 1; # On saute la ligne de titre
  17.  push @ranges, [(split(/\t/, $_))[0,1]];
  18. }
  19. close($fh1);
  20.  
  21. open $fh1, "< $input2";
  22. open $fh2, "> $output";
  23. while (<$fh1> ) {
  24.  next if $. == 1; # On saute la ligne de titre
  25.  my ($start, $end) = (split(/\t/, $_))[0,1];
  26.  foreach my $range (@ranges) {
  27.    if ( ## un certain critere ## ) {
  28.      print $fh2 $_;
  29.      last;
  30.    }
  31.  }
  32. }
  33. close($fh2);
  34. close($fh1);


Les numéros de colonnes sont 0 et 1, car j'ai testé avec les fichiers d'exemple suivants:

Start End Middle  
1000 1200 1100
2200 3000 2600
5000 6000 5000


et

Start End Genes  
980 1100 FBgn00026  
2500 5000 FBgn0027
3060 4500 FBgn0028
5200 7000 FBgn0029
5400 5800 FBgn0030
6050 8000 FBgn00036


A+,


Message édité par gilou le 12-01-2013 à 13:53:22

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2170819
cmyriam
Posté le 12-01-2013 à 11:13:10  profilanswer
 

Merci pour la reponse.
Alors je n'élimine pas FBgn0029 mais FBgn0028 car ce gene ne recouvre aucune region de mon tableau 1. C'est justement ce que je voudrais, c'est à dire garder seulement les gènes qui recouvre mes regions d'interets du tableau.  
Mon probleme est justement que je n'arrive pas a trouve quels criteres peut me permettre de faire ça.
J'espere que c'est plus claire.
A+,

n°2170836
gilou
Modérateur
Modzilla
Posté le 12-01-2013 à 13:52:58  profilanswer
 

Ah! J'ai pigé!
Le critère devrait être
($range->[0] <= $start and $start <= $range->[1]) or ($range->[0] <= $end and $end <= $range->[1])
C'est a dire que le début pour un gène est dans une zone qui vous intéresse, ou bien que sa fin l'est.
 
Au final ça fait ceci:

Code :
  1. #!/usr/bin/perl
  2. use v5.10.1;
  3. # code propre
  4. use strict;
  5. use warnings;
  6. use autodie;
  7.  
  8. use Data::Dumper;
  9.  
  10. my ($input1, $input2, $output) = ('gt1.txt', 'gt2.txt', 'gt3.txt');
  11. my ($fh1, $fh2);
  12. my @ranges;
  13.  
  14. open $fh1, "< $input1";
  15. while (<$fh1> ) {
  16.  next if $. == 1; # On saute la ligne de titre
  17.  push @ranges, [(split(/\t/, $_))[0,1]];
  18. }
  19. close($fh1);
  20.  
  21. open $fh1, "< $input2";
  22. open $fh2, "> $output";
  23. while (<$fh1> ) {
  24.  next if $. == 1; # On saute la ligne de titre
  25.  my ($start, $end) = (split(/\t/, $_))[0,1];
  26.  foreach my $range (@ranges) {
  27.    if (($range->[0] <= $start and $start <= $range->[1]) or ($range->[0] <= $end and $end <= $range->[1])) {
  28.      print $fh2 $_;
  29.      last;
  30.    }
  31.  }
  32. }
  33. close($fh2);
  34. close($fh1);


ce qui sur les données test me donne ceci en sortie:

980 1100 FBgn00026  
2500 5000 FBgn0027
5200 7000 FBgn0029
5400 5800 FBgn0030


Ce qui colle avec ce que vous m'aviez mis en exemple.
A+,


Message édité par gilou le 12-01-2013 à 13:54:41

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2170845
cmyriam
Posté le 12-01-2013 à 15:20:51  profilanswer
 

C'est exactement ça!
Merci, cela m'aide énormément.
A+,

n°2171087
cmyriam
Posté le 14-01-2013 à 14:38:14  profilanswer
 

Bonjour,
 
Je suis en train d'utiliser le script que vous m'avez donne et je vous en remercie encore.
Mais j'ai remarque que les genes qui sont beaucoup plus grand que mes valeurs ne sont pas pris en compte.
Par exemple, si j'ai dans le tableau 1:  Start    End      Middle
                                                   1000    2000    1500
Le gene:  Start    End     Middle
              800     4000     1000
Ne vas pas etre pris en compte, alors que je le voudrais.
Ne serait-il pas mieux d'utiliser la valeur "Middle" plutot que le Start et le End.
Merci.
A+,

mood
Publicité
Posté le 14-01-2013 à 14:38:14  profilanswer
 

n°2171191
gilou
Modérateur
Modzilla
Posté le 14-01-2013 à 17:41:59  profilanswer
 

Bonjour, je vois que mon critère n'était pas le bon en effet.
En fait, le bon critère est d'exclure les gènes vérifiant la proposition opposée: ils n'ont pas d'intersection avec une zone d'intérêt et donc sont avant le début ou après la fin d'une telle zone.
il suffit donc d'exclure les gènes dont la fin est avant le début de la zone d'intérêt ou dont le début est après la fin de la zone d'intérêt, et donc de remplacer la ligne
if (($range->[0] <= $start and $start <= $range->[1]) or ($range->[0] <= $end and $end <= $range->[1])) {
par
unless (($end < $range->[0]) or ($start > $range->[1])) {
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2171289
cmyriam
Posté le 15-01-2013 à 13:18:43  profilanswer
 

Merci.
Maintenant ca marche.
A+,


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  Extraire des donnees de deux tableaux

 

Sujets relatifs
copier des données de plusieurs fichiers pour en faire un seul[VB.NET] Stocker des données non visibles par l'utilisateur
quelle est la procedure qui extraire la version du hadware (firmware)[c][Transfer de donnees d´un tableau bidimensionel vers unidimensione]
Echanger simultanement des donnéesExtraire table mysql pour copier avec modif dans une autre
CSS et tableaux multiplesFichier texte trop volumineux/ extraire certaines données vers excel
Ajout données autres feuilles à la suite de la précédente 
Plus de sujets relatifs à : Extraire des donnees de deux tableaux


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR