2010-02-18 4 views
2
données

exemple:Éviter/Suppression de zéro lors de l'utilisation d'une déclaration de cas lors de l'analyse d'une chaîne

DNA : 
This is a string 

BaseQuality : 
4 4 4 4 4 4 6 7 7 7 

Metadata : 
Is_read 

DNA : 
yet another string 

BaseQuality : 
4 4 4 4 7 7 4 8 4 4 4 4 4 

Metadata : 
Is_read 
SCF_File 
. 
. 
. 

J'ai une méthode qui utilise une déclaration de cas comme suit pour séparer les éléments d'un fichier texte plus dans les enregistrements en utilisant le délimiteur "\ n \ n". Et une classe qui modélise un objet de données

def parse_file(myfile) 
    $/ = "\n\n" 
    records = [] 
    File.open(myfile) do |f| 
     f.each_line do |line| 
     read = Read.new  
     case line 
      when /^DNA/ 
      read.dna_data = line.strip 
      when /^BaseQuality/ 
      read.quality_data =line.strip 
      when /^Metadata/ 
      read.metadata =line.strip 
      else 
      puts "Unrecognized line: #{line}" 
     end 
     records.push read 
     end 
    end 
    records 
    end 

class Read 
attr_accessor :dna_data,:quality_data,:metadata 
end 

records.each do |r| 
puts r.dna_data 
end 

données adn contient la partie chaîne « qui lui revient », ainsi que deux « objets » néant/irritant de nils!

"This is a string" 
nil 
nil 

Mes problèmes sont les chaînes nulles indiquées ci-dessus qui sont affectés à dna_data lors de l'utilisation read.dna_data = line.

S'il vous plaît comment vous en débarrasser? Comment les évitez-vous en premier lieu? Qu'est-ce que je rate? Mon approche est-elle «puante»? Merci

Répondre

2

Le problème est que le code crée une nouvelle instance de Read pour chaque ligne. Au lieu de cela, il devrait créer une instance pour chaque section. Il semble qu'une partie commence par l'en-tête d'ADN, donc:

def parse_file(myfile) 
    $/ = "\n\n" 
    records = [] 
    File.open(myfile) do |f| 
    read = nil        # <- NEW 
    f.each_line do |line| 
     #read = Read.new      # <- DELETED 
     case line 
     when /^DNA/ 
     read = Read.new      # <- NEW 
     read.dna_data = line.strip 
     when /^BaseQuality/ 
     read.quality_data = line.strip 
     when /^Metadata/ 
     read.metadata = line.strip 
     records.push read     # <= ADDED 
     else 
     puts "Unrecognized line: #{line}" 
     end 
     #records.push read     # <= DELETED 
    end 
    end 
    records 
end 

Avoir le dossier analysé poussé sur le tableau les enregistrements après avoir lu les œuvres de métadonnées, mais seulement si chaque enregistrement contient toujours les métadonnées et les métadonnées est le dernier toujours. Nous pouvons rendre le programme plus indulgent des changements dans la mise en page de données en appuyant sur la lecture sur les enregistrements lors de sa création:

def parse_file(myfile) 
    $/ = "\n\n" 
    records = [] 
    File.open(myfile) do |f| 
    f.each_line do |line| 
     read = Read.new 
     case line 
     when /^DNA/ 
     records << Read.new 
     records.last.dna_data = line.strip 
     when /^BaseQuality/ 
     records.last.quality_data = line.strip 
     when /^Metadata/ 
     records.last.metadata = line.strip 
     else 
     puts "Unrecognized line: #{line}" 
     end 
    end 
    end 
    records 
end 
+1

Je pense qu'il y a un bug dans ce code: il pousse des enregistrements partiels sur le tableau des enregistrements. Il devrait seulement pousser un enregistrement en commençant une nouvelle section, ou quand le dossier est complètement lu. Si vous pouvez avoir confiance que les métadonnées sont toujours présentes et arrivent toujours en dernier, faites le push après read.metadata = ... –

+0

Oui, il y a un bug. Les métadonnées sont toujours présentes et viennent en dernier. Donc, il est logique de faire le push après read.metadata = line.strip ... s'il vous plaît laissez-moi savoir si vous obtenez une solution de contournement qui est plus générique. Merci beaucoup! – eastafri

+1

@eastafri, bug corrigé, et une nouvelle version introduite qui est moins pointilleuse sur la mise en page des données. Je m'excuse pour la mauvaise qualité de ma réponse initiale. –

0

Tout d'abord, j'éviterais d'utiliser Ruby pour la bioinformatique, ce n'est pas assez rapide pour certains problèmes. Tôt ou tard, vous rencontrerez des problèmes et votre programme s'arrêtera. D'après ce que j'ai compris, vous essayez de retirer des fichiers NIL d'un tableau. Voici deux façons de le faire:

  1. utiliser la méthode compacte.

    [nul, nul, 'asdfa']. Compact # >> [ 'asdfa']

  2. ne pas ajouter nulle lorsque vous ajoutez des éléments.

    records.push lire à moins read.nil? Records.push read if read # nil est évalué à false.

+0

Ce n'est pas une raison suffisante pour ne pas utiliser de rubis pour la bioinformatique. Ruby1.9 est assez rapide et les diverses autres implémentations Jruby, rubinius etc sont assez rapides! Deuxièmement, pour la vitesse je peux l'étendre avec C ou C++ si besoin est. et si j'ai besoin d'un idiome fonctionnel je peux l'étendre avec Haskell ou Erlang pour la concurrence. Oui Ruby est ce dynamique et le meilleur choix en fait. La vitesse n'est vraiment pas un problème car une conception ou un algorithme mal construit fonctionnera lentement que vous utilisiez C ou Java ou votre nouvelle langue super rapide.Ruby m'aide à écrire du code lisible et dynamique ... ce qui est plus important pour moi. – eastafri

+0

Votre interprétation du problème pourrait être erronée.l'objet lu ne peut pas être nul dans ce cas. Le problème se situe au moment où la ligne est assignée à la propriété appropriée. Le problème est de supprimer nil de cette chaîne. des idées de syntaxe? – eastafri

2

Vous aimeriez voir si BioRuby est adapté à vos besoins. Je l'utilise pour gérer des séquences de qualité ainsi que des séquences de nucléotides.

+0

Merci, je l'utilise aussi. L'utiliser pour publier les enregistrements ... :) – eastafri

Questions connexes