- 2配列の比較は基本的な操作
- 2配列の中に一致する部分配列があるかどうかを探索するときに、配列が作る空間中の折れ線の「平行」な部分を探索するとする
# 配列1,配列2の長さ
L1<-20
L2<-10
# 配列は4要素からなる→4次元空間に配置できる
parts<-c("A","T","G","C")
# ランダムに2配列を作成
seq1<-sample(parts,replace=TRUE,L1)
seq2<-sample(parts,replace=TRUE,L2)
#配列1の中に配列2を埋め込む
randomloc<-round(runif(1)*L1)
seq1<-c(seq1[1:randomloc],seq2,seq1[(randomloc+1):L1])
#配列を空間中の折れ線座標にする関数
makeAccumMat<-function(seq,pt){
ret<-matrix(0,length(seq),length(pt))
basenum<-which(pt==seq[1])
ret[1,basenum]<-1
for(i in 2:length(ret[,1])){
ret[i,]<-ret[i-1,]
basenum<-which(pt==seq[i])
ret[i,basenum]<-ret[i,basenum]+1
}
ret
}
#2配列を折れ線座標化する
mat1<-makeAccumMat(seq1,parts)
mat2<-makeAccumMat(seq2,parts)
#2配列の頭を揃えて、比較する関数
#2配列の距離(マンハッタン距離)の増加の様子をベクトルで返す
calcDistance<-function(mat1,mat2){
ret<-rep(0,min(length(mat1[,1]),length(mat2[,1])))
ret[1]<-sum(abs(mat1[1,]-mat2[1,]))
for(i in 2:length(ret)){
ret[i]<-ret[i-1]+sum(abs(mat1[i,]-mat2[i,]))
}
ret
}
#2配列の頭を揃えずに比較する
calcDistance2D<-function(mat1,mat2){
L1<-length(mat1[,1])
L2<-length(mat2[,1])
shorter<-min(L1,L2)[1]
longer<-max(L1,L2)[1]
ret<-matrix(0,longer-shorter+1,shorter)
for(i in 1:(longer-shorter+1)){
if(shorter==L1){
partialmat2<-mat2[i:(shorter+i-1),]
if(i!=1){
partialmat2<-t(t(partialmat2)-mat2[(i-1),])
}
ret[i,]<-calcDistance(mat1,partialmat2)
}else{
partialmat1<-mat1[i:(shorter+i-1),]
if(i!=1){
partialmat1<-t(t(partialmat1)-mat1[(i-1),])
}
ret[i,]<-calcDistance(partialmat1,mat2)
}
}
ret
}
#seq1 seq2を比較する
DistVector<-calcDistance2D(mat1,mat2)
#最も「平行」な比較は、次の図で、y=0を示す
#ミスマッチが少ない比較は、y=0から余り離れない
matplot(t(DistVector),type="b",pch=20)