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

Langage Perl Discussion :

[langage] compter les caractères d'une chaîne via un hash


Sujet :

Langage Perl

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut [langage] compter les caractères d'une chaîne via un hash
    je travaille sur des chaines d'ADN (composées de ACG ou T), et en fait je voudrais compter le nb de A, le nb de C, le nb de G, le nb de T présents dans la séquence.

    Voici ce que je faisias jusqu'à présent:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    while ( $sequence =~ /A/gi)
    { $A =$A+1; }
     
    while ( $sequence =~ /G/gi)
    { $G =$G+1; }
     
    while ( $sequence =~ /U/gi)
    { $U =$U+1; }
     
    while ( $sequence =~ /C/gi)
    { $C =$C+1; }
    mais on m'a conseillé de faire autrement, car j'ai besoin d'accéder très fréquement à $A $G $C et $G. On m'a conseillé de mettre ma séquence dans une liste, puis de mettre les résultats du comptage au fur et à mesure dans un hash mais je ne vois pas trop comment faire.....

    Kinethe

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 90
    Points : 96
    Points
    96
    Par défaut
    salut,

    je ne sais pas si bioperl est installe sur ton pc/mac/serveur, mais si oui et si tu cherches a compter le nombre d'occurences d'une base dans une sequence tu peux faire
    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
     
    #!/bin/perl -w
     
    use strict;
    use diagnostics;
    use warnings;
    use Bio::Seq;
    use Bio::Tools::SeqStats;
     
     
     
    my $sequence = "GCGATATATCGCGCGATATCGCGCCG";
     
    my $seqobj=Bio::Seq->new (-seq => $sequence);
    my $hash_ref = Bio::Tools::SeqStats->count_monomers($seqobj);
    foreach my $base (sort keys %$hash_ref) {
      print "Number of bases of type ", $base, "= ", %$hash_ref->{$base},"\n";
    }
    avec la sequence donnee en exemple cela donne la sortie suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Number of bases of type A= 5
    Number of bases of type C= 8
    Number of bases of type G= 8
    Number of bases of type T= 5
    sinon pour mettre les résultats du comptage au fur et à mesure dans un hash, je pense que c'est le meme principe que au dessus
    tu as une table de hachage qui est du type
    $ref{'base A'} = nbr d'occurence de A
    $ref{'base T'} = nbr d'occurence de T
    $ref{'base G'} = nbr d'occurence de G

    mais je n'ai pas tres bien saisi le 'j'ai besoin d'accéder très fréquement à $A $G $C et $G'
    tu penses avoir des pb de performances avec ton code actuel ?

    [edit]
    encore une chose
    plutot que de faire ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while ( $sequence =~ /A/gi)
    { $A =$A+1; }
    tu peux faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $A= ( $sequence =~ s/A/A/g);
    en fait tu fais simplement un remplacement de A par A mais la fonction de substitution te renvoie le nombre de remplacement effectues (qui sont alors stockes dans $A)
    Ce doit etre plus rapide comme cela t'evites de passer par un while

    et tu peux meme faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $my_seq{'A'}= ( $sequence =~ s/A/A/g);
    comme ca tu stockes bien tes resultats dans une table de hash %my_seq
    [/edit]

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    j'ai réussi à coder qlq chose qui marche mais seulement lorsque j'ai déjà une liste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #!/usr/bin/perl
     
    use strict;
     
    my @sequence= qw (G C G A A C G C A T C A T A T T A C C C A A T T );
    my %comptage = ();
     
    foreach my $base (@sequence)
    { $comptage {$base}++; }
     
    while ( my ($k, $v) = each (%comptage))
    { print "La base $k est present $v fois \n"; }
    or dans mon programme je travaille sur des séquences, dc j'aimerai à partir des séquences passer à des tableau. J'ai vu que la fonction split le faisait très bien.... mais pourtant ça ne marche pas.....

    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
     
    #!/usr/bin/perl
     
    use strict;
     
    my $sequence; #="GTTCCAAAAACAGTGGATAGTGGCCTTAAT";
    my @sequence = split ( / /, $sequence);
    print @sequence;
     
    my %comptage = ();
     
    foreach my $base (@sequence)
    { $comptage {$base}++; }
     
    while ( my ($k, $v) = each (%comptage))
    { print "La base $k est present $v fois \n"; }
    Que faire?

    Kinethe

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    j'ai oublié d'enlever le commentaire dans la ligne
    my $sequence; #="GTTCCAAAAACAGTGGATAGTGGCCTTAAT";
    3è ligne du code

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 90
    Points : 96
    Points
    96
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @sequence = split ( //, $sequence);
    ceci marche
    si tu veux splitter sur chaque caractere, tu dois utiliser un pattern vide dans la fonction split, la tu avais mis / /, le split cherchait a plitter a chaque espace

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 90
    Points : 96
    Points
    96
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    my @caracteres = qw (A T G C);
     
    my $sequence="GTTCCAAAAACAGTGGATAGTGGCCTTAAT";
     
    my %comptage = ();
     
    foreach my $base (@caracteres){
    $comptage{$base}= ( $sequence =~ s/$base/$base/g);
    }
    #test
    foreach my $char (keys %comptage) {
    print "il y a $comptage{$char} $char\n";
    }
    avec ce code tu peux ajouter des caracteres facilement (si un jour tu dois aussi compter les N ou prendre en compte le code IUPAC)
    et tu te passe du split et du foreach qui doivent etre gourmand en temps de calcul

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    génial, c'est exaactement ce que j'avais l'intention de faire, de compter les N et tous ce qui est caractères étranger, je vais le tester tout de suite
    merci

    Kinethe :o

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    ok ca marche très bien, MERCI

    par compte comment faire si je ne veux afficher que le résultat du "comptage" de certaine base, par exemple seulemnt le nb de A?

  9. #9
    Membre actif
    Avatar de Choupi
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 223
    Points : 235
    Points
    235
    Par défaut
    print "il y a $comptage{A} A\n";
    par exemple.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 90
    Points : 96
    Points
    96
    Par défaut
    Choupi is back

  11. #11
    Membre actif
    Avatar de Choupi
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 223
    Points : 235
    Points
    235
    Par défaut
    Que pour t'embeter

    Choupi -> <- fsapet qui code en perl (desole de pourrir ton topic )

    Ok j'edite

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 90
    Points : 96
    Points
    96
    Par défaut
    hummmmm

    je dechaine les passions a ce point !

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    maintenant j'ai un pbl au niveau de la fonction,
    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
     
    #!/usr/bin/perl
    use strict;
    use warnings; 
     
    my $sequence="GTTCCAAAAACAGTGGNNATAGTGGCCTNTAATGGG"; 
    my %comptage;
     
    sub COMPTE_CARACTERE
    {
    my $sequence = @_; 
    my @caracteres = qw (A T G C N);
    my %comptage = (); 
    foreach my $base (@caracteres)
    { $comptage{$base}= ( $sequence =~ s/$base/$base/g); }
    foreach my $char (keys %comptage) 
    { print "il y a $comptage{$char} $char\n";}
    }
     
    COMPTE_CARACTERE ();
     
    print "Le nb de A est $comptage{A} \n"; 
    print "Le nb de C est $comptage{C} \n";
    mais la fonction ne "print" rien. Est-ce que je dois mettre un return?

  14. #14
    Membre actif
    Avatar de Choupi
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 223
    Points : 235
    Points
    235
    Par défaut
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    my $sequence="GTTCCAAAAACAGTGGNNATAGTGGCCTNTAATGGG";
    my @caracteres = qw (A T G C N);
    my %comptage;
     
    sub COMPTE_CARACTERE
    {
    foreach my $base (@caracteres)
    { $comptage{$base}= ( $sequence =~ s/$base/$base/g); }
    foreach my $char (keys %comptage)
    { print "il y a $comptage{$char} $char\n";}
    }
     
    COMPTE_CARACTERE ();
     
    print "Le nb de A est $comptage{A} \n";
    print "Le nb de C est $comptage{C} \n";
    Tu avais redefini toutes tes variables dans la fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    il y a 10 A
    il y a 8 T
    il y a 3 N
    il y a 5 C
    il y a 10 G
    Le nb de A est 10
    Le nb de C est 5

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    encore une petite question....avant d'ajouter le tag RESOLU
    comment je peux regrouper tout les caractères qui ne sont ni des "A", "C", "G" ni des "T" dans un même compteur?
    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
     
    #!/usr/bin/perl
    use strict;
    use warnings; 
     
    my $sequence = "GTTCCAAAAACAGTGGATANGTNGGNMPM4545AT";
    my @caracteres = qw (A T G C N);
    my %comptage = (); 
     
    sub COMPTE_CARACTERE
    {
     
    foreach my $base (@caracteres)
    { $comptage{$base}= ( $sequence =~ s/$base/$base/g); }
    foreach my $char (keys %comptage) 
    { print "il y a $comptage{$char} $char\n";}
    }
     
    COMPTE_CARACTERE ();
    Par exemple je compte tous les caractères autres que les bases c'est-à-dire ( ds ce cas ) MPM4545 + les 3 N = 10 caractères différents que les bases

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 90
    Points : 96
    Points
    96
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @caracteres = qw (A T G C [^ATGCN]);
    j'ai teste ca, ca marche, mais je ne crois pas que ce soit tres classieux !

    mais sinon tu peux calculer la longueur de la chaine et retrancher les A T G C et N, et le reste correspond aux autres caracteres

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    j'ai une autre question

    en fait dans plusieur endroit de mon code, je vais avoir besoin de connaitre la composition en caractères de ma séquences. Dc je vais faire plusieur fois appel à la fonction. Quel est la meilleure facon pour récupérere ces valeurs plusieurs fois :

    *** soit: je fais un return dans ma fonction :
    return ($comptage{A},$comptage{T},$comptage{C},$comptage{G})
    puis je l'appel par: ($comptage{A},$comptage{T},$comptage{C},$comptage{G}) = COMPTE_CARACTERE ($sequence);

    *** soit : je "print" directement les valeurs
    print "Le nb de A est $comptage{A} \n";
    #print "Le nb de C est $comptage{C} \n";
    #print "Le nb de G est $comptage{G} \n";
    #print "Le nb de U est $comptage{U} \n";
    #print "Le nb de N est $comptage{N} \n";
    En fait, quelle est la différence et quelle est la meilleure façon??

    merci

    Kinethe

  18. #18
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    mais sinon tu peux calculer la longueur de la chaine et retrancher les A T G C et N, et le reste correspond aux autres caracteres
    j'y avais pensé, mais je pensais qu'il existait peut-être une méthode + "classieuse"!!

    merci

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 90
    Points : 96
    Points
    96
    Par défaut
    Re-Salut

    je ne comprends pas bien ton pb, tu n'pas besoin de faire appel plusieurs fois a ta fonction (sauf si tu veux effectuer des comptages sur d'autres sequences), a partir du moment ou tu lances ta fonction une fois, ton hash %comptage est rempli et tu peux afficher ses valeurs

    et sinon je pense qu'il faut que tu revois le fonctionnement des SUB
    par exemple dans ton cas, il faut que tu donnes un argument a ta fonction (la sequence a decortiquer) et que tu retourne le hash qui contient les resultats
    comme ca tu peux appeler ta focntion plusieurs fois dans ton script avec en arguments des sequences differentes et tu recuperes les resultats dans des hash differents

    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 $sequence="GTTCCAAAAACAGTGGATAGTGGCCTTAATRRRRRR";
    my $sequence_bis="acttdvcgtatcgtdtgagcgtdtvagctdtagcgvatatgcgaccgtagcbnantcga";
     
    sub count_bases {
     
      my ($sequence) = @_;
      my %comptage;
      my $length = length ($sequence);
      my @caracteres = qw (A T G C );
      foreach my $base (@caracteres){
        $comptage{$base} = ( $sequence =~ s/$base/$base/g);
        $length  = $length - $comptage{$base};
      }
      $comptage{'OTHER'} = $length ;
      return (%comptage);
    }
     
    my %count_for_seq1 = count_bases ($sequence);
    #test
    foreach my $char (keys %count_for_seq1) {
    print "il y a $count_for_seq1{$char} $char\n";
    }
    my %count_for_seq2 = count_bases ($sequence_bis);
    #test
    foreach my $char (keys %count_for_seq2) {
    print "il y a $count_for_seq1{$char} $char\n";
    }

  20. #20
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 67
    Points : 34
    Points
    34
    Par défaut
    Génial ton dernier code, très "classieux" même!

    merci bcp

    a+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 28/05/2012, 15h53
  2. [MySQL] Compter les stocks, soucis pour ecrire une requete
    Par maxromeo dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 17/08/2011, 13h59
  3. [XL-2003] Compter les changements de valeur dans une colonne
    Par clem71 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 16/04/2009, 00h09
  4. Compter les lignes du résultat d'une requete
    Par mfavier dans le forum ASP
    Réponses: 4
    Dernier message: 30/06/2006, 21h05
  5. [langage] compter les retour à la ligne
    Par Kinethe dans le forum Langage
    Réponses: 4
    Dernier message: 16/07/2004, 16h36

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