IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bioinformatique Perl Discussion :

algo-> associer un couple à


Sujet :

Bioinformatique Perl

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 142
    Points : 57
    Points
    57
    Par défaut algo-> associer un couple à
    Bonjour,

    j'ai un fichier fam.txt contenant les familles et nom d'enfant et un autre fichier enfant.txt contenant les couples d'enfants
    (chaque famille a 2 enfants; cela fonctionne par couple)
    Je souhaiterai obtenir un fichier final qui m'indique le nom de la famille et le couple d'enfants associés.

    fam.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    dupond    jules
    martin     fred
    brun	      anna
    martin     felix
    minh	      emma
    dupond     james
    brun         jules
    duvernet   alice
    enfant.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    jules      james
    felix      fred
    anna      alice
    fichier final
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    jules      james
    felix      fred
    anna      alice
    Mon problème au niveau de l'algo, je ne vois pas comment construire mon script.

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 142
    Points : 57
    Points
    57
    Par défaut
    Voiçi mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    my $fichier = 'fam.txt';
    open my $fh, '<', $fichier or die "Impossible de lire le fichier $fichier\n";
     
     
    my %hash=();
     
    while(my $ligne = <$fh>){
            chomp $ligne;
            my ($famille,$gene) = split "\t", $ligne;
            $hash{$gene}=$famille;
    }
     
    open ALL, "enfant.txt" or die $!;
    while(my $ligne = <ALL>){
            chomp $ligne;
     
    	if($ligne =~ /(.*)\t(.*)$/){
    		if (exists $hash{$1}){
                    	print "$hash{$1}\t$ligne\n";
    		}
    		else{
    			$l++;
    			#print "$gene\n";
    		}
    	}
    }
    J'obtiens pour mon fichier final:
    brun jules james
    martin felix fred
    brun anna alice

    Or anna est fille de la famille brun et alice de duvernet!!!

  3. #3
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    tes données en entrée ne sont pas cohérentes (si du moins j'ai bien compris).

    Le fichier enfant.txt contient la ligne:
    ce qui indique, d 'après ce que tu dis, qu'elles sont sœurs, mais elles ne portent pas le même nom de famille. C'est donc incohérent. Même si ton programme est juste, il va forcément sortir une incohérence, sur le nom de famille s'il donne la priorité aux fratries du fichier enfant.txt, ou sur les fratries s'ils donne la priorité aux noms de famille.

    En fait, les informations du premier fichier sont suffisantes à elles seules pour résoudre le problème, le fichier enfant.txt est parfaitement inutile (et il est même nuisible s'il n'est pas cohérent).

    Tu as juste besoin de créer à partir du premier fichier un hash avec comme clé le nom de famille et comme valeur la liste des enfants pour résoudre le problème à partir du premier fichier, sans utiliser le second.

  4. #4
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    du même avis que LoLo car je me suis posé les même questions !

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 142
    Points : 57
    Points
    57
    Par défaut
    Bonjour,

    Merci pour vos réponses.

    "En fait, les informations du premier fichier sont suffisantes à elles seules pour résoudre le problème, le fichier enfant.txt est parfaitement inutile (et il est même nuisible s'il n'est pas cohérent).

    Tu as juste besoin de créer à partir du premier fichier un hash avec comme clé le nom de famille et comme valeur la liste des enfants pour résoudre le problème à partir du premier fichier, sans utiliser le second. "

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    my $fichier = 'fam.txt';
    open my $fh, '<', $fichier or die "Impossible de lire le fichier $fichier\n";
     
     
    my %hash=();
    my @list=();
     
    while(my $ligne = <$fh>){
            chomp $ligne;
            my ($famille,$gene) = split "\t", $ligne;
     
            if (exists $hash{$famille}){
                     push(@list, $hash{$famille},$gene);
                     $hash{$famille}= $hash{$famille}." ".$gene;#remplir le hash
                     next;
    	}
            $hash{$famille}=$gene;
    }
    # affichage
    foreach my $t (keys %hash){
            print  "clé: $t\tvaleur: $hash{$t}\n";#verif
    }

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 142
    Points : 57
    Points
    57
    Par défaut
    Je vais essayer de m'expliquer autrement

    J'ai 2 fichiers
    fichier 1 : Pour chaque famille j'ai une liste de gène présent (chaque gène est séparé par une tabulation)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    fam1   ptv5 ptv10rd_6 ptv468 rm63 rm69
    fam5   ptv20 ptv16  rm6
    fam3    ptv15 ptv 6 ptv9 rm52 rm123
    fichier 2 : un couple de gène
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ptv5 rm69
    ptv3 rm5
    je souhaiterai pour chaque couple de gène de mon fichier 2, savoir si ils appartiennent tous deux à la même famille et donc obtenir un fichier final contenant les couples de gènes présent dans la même famille

    fichier final:

  7. #7
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Points : 406
    Points
    406
    Par défaut
    quelques idées comme ça car je 'ai pas trop le temps de coder/tester aujourd'hui:
    - si tu fais ton hash du fichier1 dans l'autre sens: hash{$gene}=$famille ou ($famille1, $famille2...) car je sais pas si 1 gène peut appartenir à plusieurs familles dans ton cas

    - tu pourras ensuite en lisant ton fichier2 faire la comparaison des 2 famille correspondant aux 2 gènes du couple: si identique, ajout de la famille pour le fichier de sortie

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 142
    Points : 57
    Points
    57
    Par défaut
    Merci, ça m'a beaucoup aidé!
    Par contre à priori c'est long, mes fichier 1 et 2 étant énorme.
    Il n'y aurait pas une autre façon de faire plus rapide?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    my $fichier = 'fichier1';
    open my $fh, '<', $fichier or die "Impossible de lire le fichier $fichier\n";
     
    my %hash=();
     
    while(my $ligne = <$fh>){
            chomp $ligne;
    	if($ligne =~ /^(.*)\t(.*)$/) {
        		my $fam=$1;
    		$hash{$3}=$fam;
    	 }
    }
     
    open FILE, "fichier2" or die $!;
    while(my $ligne = <FILE>){
            chomp $ligne;
    	my ($element1,$element2) = split "\t", $ligne;
    	foreach my $t (keys %hash){
    		my @list = split "\t",$t;
    		my $pr=0;
    		foreach my $gene (@list) {
    			if($gene eq $element1){
    				$pr++;
    			}
    			if($gene eq $element2){
    				$pr++;
    			}
    		}
    		if($pr==2) {
    			print "$hash{$t}\t$hs\t$pantr\n";
    		}
    	}
    }

  9. #9
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    un premier point est que cette regex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if($ligne =~ /^(.*)\t(.*)$/)
    est a priori très inefficace car elle fait beaucoup de retours arrière (backtracking). Essaie plutôt:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if($ligne =~ /^(.*?)\t(.*)$/)
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if($ligne =~ /^([^\t]*)\t(.*)$/)
    La lecture du premier fichier devrait être significativement plus rapide. Fais éventuellement un test sur la seule lecture du premier fichier pour vérifier.

    Point accessoire: je ne comprends pas d'où vient $3 dans ta regex (il n'y a que deux paires de parenthèses capturantes).

    Cela dit, c'est sans doute surtout la deuxième partie de ton programme qui prend beaucoup de temps, avec sa triple boucle imbriquée. Je suis persuadé que l'on peut faire beaucoup beaucoup mieux en modifiant l'algo, mais je n'ai pas le temps de me pencher en détail dessus maintenant.

    Au minimum, faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @list = split "\t",$t;
    pour chaque ligne du fichier 2 en entrée est très inefficace, il faut ne le faire qu'une seule fois avant d'attaquer le fichier 2, en utilisant un hash de tableaux, par exemple.

    Mais, comme je l'ai dit, je pense surtout qu'il faut réviser l'algo de fond en comble pour éviter cette triple boucle. Mais là, je ne peux te conseiller maintenant , il me faudrait du temps pour comprendre exactement ce que tu fais dans ton programme et trouver une meilleure solution, je suis pratiquement sûr qu'il y en a une, mais je n'ai pas le temps maintenant. J’essaierai de revenir plus tard.

    Entre temps, si tu peux fournir des données en entrée plus conséquentes (au moins quelques centaines de lignes pour chaque fichier) dans des fichiers attachés, cela permettrait de mieux comprendre ton besoin et de tester des solutions alternatives.

  10. #10
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Points : 406
    Points
    406
    Par défaut
    comme l'a dit Lolo la triple boucle est assez couteuse et si j'ai bien compris le problème ce n'est pas nécessaire

    dans ton 1er fichier tu "fais" les couples gène/famille
    ensuite tu ne veux mettre dans ton nouveau fichier les lignes que si les 2 gènes sont de la même famille alors inutiles de regarder toutes les combinaisons (boucles imbriquées) mais juste les familles des 2 gènes de la ligne

    j'ai pas trop le temps de tester mais si tu rencontre des problèmes dis le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    my $fichier = 'fichier1';
    open my $fh, '<', $fichier or die "Impossible de lire le fichier $fichier\n";
     
    my %hash=();
     
    while(my $ligne = <$fh>){
            chomp $ligne;
    	if($ligne =~ /^(.*)\t(.*)$/) {
        		my $fam=$1;
    		$hash{$2}=$fam;
    	 }
    }
     
    open FILE, "fichier2" or die $!;
    while(my $ligne = <FILE>){
            chomp $ligne;
    	my ($element1,$element2) = split "\t", $ligne;
    	#Verif que les 2 éléments sont de la même famille
    	if ($hash{$element1} eq $hash{$element2}){
    		print "$hash{$element1}\t$element1\t$element2\n";
    	}
    }

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 142
    Points : 57
    Points
    57
    Par défaut
    Bonjour,

    Mon algo ne focntionne pas, merci Djibril mais cela ne fonctionne pas non plus.
    $hash{$2} est une liste de gènes séparé par une tabulation; donc il faut bien splitté pour considérer chaque élément individuellement


    fichier 1 -> pour chaque famille (champ 1), on a la liste de gènes (champ 2 à champ x)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fam1	   ptv5	ptv10rd_6	ptv468	rm69
    fam5	   ptv20	ptv16	rm6      rm4
    fam3	   ptv15  	ptv6	ptv9	rm52 rm123
    un gène appartient à une famille

    fichier 2 -> gene 1 (champ1) et gene 2 (champ2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ptv5	  rm69
    ptv15	  rm4
    pt5	  rm8
    ptv20	rm6
    ptv3    rm123
    ptv12  rm185

    Je souhaiterai écrire un algo qui me permette d'obtenir un nouveau fichier avec les lignes que si les 2 gènes sont de la même famille
    nouveau fichier:
    et avoir le décompte:
    nombre de cas pour lesquels les 2 gènes sont dans des familles différentes du fichier 1 (soit ici : ptv15 et rm4)
    nombre de cas pour lesquels un gène est dans une famille du fichier 1 et l'autre non (soit ici : ptv3 et rm123)
    nombre de cas pour lesquels les 2 gènes ne sont pas dans les familles du fichier 1 (ptv12 rm185)

  12. #12
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    OK, tout dépend de la taille de tes fichiers, tu as dit qu'ils sont énormes, mais sans donner d'indication chiffrée de leur taille.

    S'ils ne sont pas trop énormes, essaie de faire la chose suivante:
    - Lire le premier fichier et stocker les données dans un hash de la façon suivante: chaque gène est une clé et la famille est une valeur (ce qui doit marcher puisque tu as dit que chaque gène est unique)
    - Lire le second fichier, pour chaque ligne, prendre le premier gène, déterminer sa famille à l'aide du hash (s'il existe), puis vérifier si le second gène existe et appartient à la même famille, et imprimer dans les fichiers de sortie selon les cas.

    Ainsi, tu n'as plus de boucles imbriquées, ça ira énormément plus vite.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 142
    Points : 57
    Points
    57
    Par défaut
    Hello,

    Merci je vais essayer de faire comme tu indiques.
    ls -sh fichier1
    89M
    ls -sh fichier2
    717K

  14. #14
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    89 MO, ça devrait passer sans problème, je pense. Pour moi qui manipule des fichiers de plusieurs gigas, 89 megas, c'est juste un peu gros, pas énorme.

  15. #15
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Points : 406
    Points
    406
    Par défaut
    As-tu testé ma proposition? car je pense qu'il correspond à l'algo de @Lolo

    Si ça ne fonctionne pas et que tu as besoin d'aide dis-le on t'aidera

  16. #16
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Je confirme que le code de Cyril correspond à peu près à l'algo que j'ai proposé récemment.

Discussions similaires

  1. Associer un résultat d'un calcul à des couples de valeurs
    Par wahouuu0 dans le forum Macros et VBA Excel
    Réponses: 39
    Dernier message: 04/05/2015, 13h43
  2. Association de couple pour création de ligne unique
    Par MDsas dans le forum SAS Base
    Réponses: 10
    Dernier message: 02/02/2012, 14h33
  3. Réponses: 12
    Dernier message: 14/10/2011, 21h52
  4. Cherche l'algo crc 16 bits
    Par icepower dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 21/08/2002, 13h27
  5. [Kylix] icone associée à un programme
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo