2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

エクセルVBAで動的計画法でDNA配列のアラインメントを作成 Needleman-Wunschアルゴリズムの実装

Posted at

はじめに

この記事は、DNA配列のアラインメントを返すエクセルの関数についての記事です。

Needleman-Wunschによるアルゴリズムによるアラインメントですので関数名はnwa()としました。

方針

最終的に作る関数は、
image.png
とすると、以下のようなアラインメントを返す関数です。
image.png

エクセルシート上で、アルゴリズムを示した後で、関数の作成に取り掛かります。

エクセルシート上でアルゴリズムをチェック

2つの行列を用意します。アラインしたい2つのDNA配列の長さをmとnとすれば、縦m x 横nの大きさの行列です。行列は、スコア行列と、トレースバック行列です。初期状態は以下の通りです。

2つのDNA配列は、一文字ずつ区切ってセルに入れ、行と列のラベルとして使います。

スコア行列

初期状態を以下のようにします。
image.png

トレースバック行列

初期状態を以下のようにします。
image.png

行列の埋め方

一定の規則に従って、行列を左上から埋めていきます。規則は以下の通りです。
これから埋めようとするセルの番地をx,yとした時に、以下の3つのスコアのうち、最も高いスコアをセル(x,y)の値とする(2つ以上が同じ値で、最高値になることもある)。

  1. そのセルに対応する塩基が同じ場合(セルの列ラベルと行ラベルを比べて同じ場合)、セル(x-1,y-1)の値に1を加えた値、そうでなければ、セル(x-1,y-1)の値から1を減じた値
  2. セル(x-1,y)の値から1を減じた値
  3. セル(x,y-1)の値から1を減じた値

要するにセル(x-1,y-1)は左上のセル、セル(x-1,y)は左のセル、セル(x,y-1)は上のセルです。
またこの時、トレースバック行列の対応するセルにも値を入れます。規則は、

  1. 最高スコアを示したのが「1」だったら、LEFTUP
  2. 最高スコアを示したのが「2」だったら、LEFT
  3. 最高スコアを示したのが「3」だったら、UP、
    とします。

エクセル上では、こんな風になります。MAXは、引数の中から最大値を返す関数です。後でコピーペーストする用に、絶対参照を使っています。
image.png
こっちはちょっとややこしいですね。
image.png

あとは作った式をコピーペーストして行列を埋めます。
image.png

トレースバック行列の右下のセルから、記しておいた通りに、さかのぼっていきます。LEFTUPと書いてあったら左上に飛ぶ、というようにします。辿ったセルの背景を赤くしておきました。

image.png

これで、2つの配列をどう並べたら良いかがわかったことになりますが、この行列をもとにVBAを使わないでアラインメントを作るのは大変なので、以後はVBAで関数を作ります。

VBAコード

アルゴリズムさえわかってしまえば、特に難しいところはないですね。ここでは二次元の行列の代わりに、一次元の行列を使っています。幅nの行列の座標(x、y)は、一次元行列では、indexが$x + n*y$になります。

'DNA配列を2つ受け取ります。DNAXとDNAYとします。

Public Function nwa(DNAX As String, DNAY As String) As String

Dim n As Integer
Dim m As Integer
Dim u As Integer
Dim l As Integer
Dim ul As Integer
Dim score As Integer
Dim alignmentX As String
Dim alignmentY As String
Dim alignmentLine As String

alignmentX = ""
alignmentY = ""
alignmentLine = ""
n = Len(DNAX)
m = Len(DNAY)

Dim scm() As Integer 'スコアマトリックスscm
Dim trm() As String 'トレースバックマトリックス trm
ReDim scm(0 To n * m)
ReDim trm(0 To n * m)


'マトリックスの初期化
For K = 1 To n - 1
    scm(K) = -2 * K
    trm(K) = "LEFT"
Next K

For J = 1 To m - 1
    scm(J * n) = -2 * J
    trm(J * n) = "UP"
Next J

'規則従って2つのマトリックスを埋める
For Y = 1 To m - 1
    For X = 1 To n - 1
        u = scm(X + (Y - 1) * n) - 1
        l = scm(X - 1 + Y * n) - 1
        If Mid(DNAX, X, 1) = Mid(DNAY, Y, 1) Then
            ul = scm(X - 1 + (Y - 1) * n) + 1
            Else
            ul = scm(X - 1 + (Y - 1) * n) - 1
        End If

        If ul >= u And ul >= l Then
                scm(X + Y * n) = ul
                trm(X + Y * n) = "LEFTUP"
        ElseIf u >= ul And u >= l Then
                scm(X + Y * n) = u
                trm(X + Y * n) = "UP"
        ElseIf l >= ul And l >= u Then
                scm(X + Y * n) = l
                trm(X + Y * n) = "LEFT"
        End If
    Next X
Next Y


'スコア算出と、アラインメントの作成
'アラインメントの各行を別々に作って最後に足し合わせる。
'ギャップ部分は - を挿入
score = 0
X = n - 1
Y = m - 1
While X <> 0 Or Y <> 0
        q = trm(X + Y * n)
        If q = "LEFT" Then
            alignmentX = Mid(DNAX, X, 1) & alignmentX
            alignmentY = "-" & alignmentY
            alignmentLine = " " & alignmentLine
            X = X - 1
        ElseIf q = "UP" Then
           alignmentX = "-" & alignmentX
            alignmentY = Mid(DNAY, Y, 1) & alignmentY
            alignmentLine = " " & alignmentLine
            Y = Y - 1
        ElseIf q = "LEFTUP" Then
            If Mid(DNAX, X, 1) = Mid(DNAY, Y, 1) Then
                score = score + 1
                alignmentLine = "|" & alignmentLine
                Else
                alignmentLine = " " & alignmentLine
            End If
            alignmentX = Mid(DNAX, X, 1) & alignmentX
            alignmentY = Mid(DNAY, Y, 1) & alignmentY
            X = X - 1
            Y = Y - 1
        End If
Wend

'VBA関数の作り方のルールに従って、最後に関数名=返り値とする。
nwa = alignmentX & vbNewLine & alignmentLine & vbNewLine & alignmentY
End Function

終わりに

最後にscoreを返すように変更すれば、そういう使い方もできますね。

以前作った関数ですが、ここで公開することにしました。かつて読んだ本にあった解説がなかなか理解できず、煩悶したことがあります。ここでの記事が、悩める人の理解の助けになれば幸いです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?