バイオインフォマティクス
Rubyプログラミング入門
PHYLIP形式のデータ整形プログラムphylip.rbの解説
このプログラムはClustalWでアラインした配列の出力(seq.aln)をPHYLIPで解析できる形に整形するプログラムである。
1| data = Hash.new
2| while line = ARGF.gets
3| unless /CLUSTAL|\*/ =~ line
4| x = line.chomp.split(/ +/)
5| unless x[0].nil?
6| if data.key?(x[0])
7| data[x[0]] << x[1]
8| else
9| data[x[0]] = x[1]
10| end
11| end
12| end
13| end
14| puts "#{data.size} #{data.values.first.size}"
15| data.each do | k,v |
16| if k.size >= 10
17| print k[0..9]
18| else
19| print k+" "*(10-k.size)
20| end
21| puts v
22| end
- 1行 「ハッシュ」という形式のデータ、dataを定義する。dataは塩基配列名をキーとし、塩基配列を値に持つ。
- 2行 Rubyでファイルを読み込み、1行ずつ処理するときの慣用句。13行のendと対になっている。ARGFは特殊な変数で、コマンドラインで指定したファイルを表している。例えば、ruby phylip.rb test.txtとして実行したとき、ARGFはtest.txtのことを指す。whileは後に続く条件がtrueである限りendまでを繰り返す。ここではARGFから1行読み込み、lineという変数に入れている。Rubyでは条件式(a == 0 や x > 'g'など)が成立するかどうか以外にも式の値がnilならば不成立、そうでなければ成立する。ファイルにデータがある限り、lineには何かの値が入っているため、条件は成立しているが、ファイルの最後に来て、読み込むデータがなければlineにはnilが入り、line = ARGF.getsもnilを返すため、ループを終了する。
- 3行 ClustalWの出力で、PHYLIP形式に必要ない行をスキップする。unlessはifと似ているが、後ろの条件が成立しないときにendまでを実行する。条件には正規表現を使っている。この場合、CLUSTALという文字または*を含む行について条件が成立するので、これらの行は処理しない。
- 4行 chompは読み込んだ行の最後にある改行記号を取り除く。splitは引数(この場合は連続したスペース)でレシーバーの文字列(この場合はlineをchompで処理した結果の文字列)を切り分けた結果を配列として返す。ClustalWの出力ならx[0]には塩基配列の名前、x[1]には塩基配列がはいる。
- 5行 読んだ行にデータが何もないとき(空行)はx[0]がnilになっている。このときは処理を行わない。
- 6-10行 読み込んだ配列名がすでにハッシュのキーとして存在していれば、その値に読んだばかりの塩基配列を追加する。もし、まだハッシュになければ、つまり、初めて出てきた配列なら新しくハッシュに追加する。
- 14行 PHYLIP形式では先頭行に塩基配列の数とその長さを書くことになっているため、ここで実行している。ハッシュのvaluesメソッドはすべての値を配列として返す。並び順は特に決まっていない。次のfirstで値の配列の最初のデータを取り出し、その長さを求めている。ClustalWの出力ではすべての塩基配列の長さがそろえられているため、これでよい。
- 15行 ハッシュのeachメソッドはそのハッシュのすべてのデータを順にキー、値の組でブロック(doとendの間、16-21行)に渡す。
- 16-20行 PHYLIP形式では塩基配列名が10文字に決まっているので、10文字より長い時は最初の10文字を書き出し、そうでなければ10文字に足りない分を空白で補う。文字列の*メソッドはその文字列を指定した回数繰り返した文字列を返す。printメソッドを使っているので、配列名を書いた後は改行しない。
- 21行 塩基配列を書き出す。今度は改行したいのでputsを使っている。
トップページへ
2009年7月27日作成、2011年6月6日更新
國分 尚 (Hisashi Kokubun)
hkokubun@faculty.chiba-u.jp