- マーカーが相互に独立な場合には、個々のマーカーに関して確率・尤度を計算して、積を取ることができる
- ゲノム全体にぱらぱらと置いたIdentifilerの場合には、この仮定でよい
- マーカーごとに次のように考える
- アレル数がのとき、ディプロタイプのタイプ数はある
- ディプロタイプの情報がなければ、すべてのディプロタイプをすべての個人が取りうるものとして考えることになります。人数がならば通りが考えられます
- ディプロタイプが既知のメンバー(家系情報行列の第5カラムが1)がいるときには、その分を減らせるが、家系が大きかったり、タイプが2,3のメンバーの数が複数のときには、計算量が十分大きく、現実的ではない
- 家系情報とディプロタイプ既知メンバーのディプロタイプ情報を用いて、ディプロタイプ不明メンバーの取りうるディプロタイプや、伝達(継承)情報が限定できる
- そのルールは『子は両親の持つ2アレルの片方を受け継ぐ』こと
- これが以下のようにいろいろな制約をもたらす
- 子は由来親の持っていないアレルは受け取れない
- 子は両親から伝達される可能性のないアレルはディプロタイプに持ちえない
- 子の由来親から受け取れないアレルの数がアレル総数-1に等しいとき、そのアレルは受け取るアレルとして確定する
- 子が必ず持つアレルことがわかっているアレルのうち、父(母)由来でないアレルは、必ず母(父)からの伝達アレルである
- 子が由来親から伝達することが確実なアレルが1つあるとき、それ以外のアレルが伝達されることはない
- 子が由来親から伝達されることがあり得ないアレルの数がアレル総数-1に等しいとき、伝達される可能性のあるアレルは確実に伝達アレルであるとわかる
- この処理に必要なのは、家系情報とディプロタイプとアレル総数である
- 以下のソースは、長く、また汚く、返り値もごちゃごちゃした段階であるが、「ディプロタイプ」と「伝達ハプロタイプ」をそれぞれ出力すること、それを集合として扱うことと、ベクトルとして扱うこと、また、アレル名称で扱うことと、アレルにつけたシークエンスIDで扱うために、重複していることが主な理由で、その視点でみると、それほど複雑ではない
LimitDiplotypeZ<-function(p,g,A){
unknown="0"
ns<-length(p[,1])
na<-length(A)
D<-matrix(0,ns,na)
H<-array(0,c(ns,2,na))
for(i in 1:ns){
if(g[i,1]!=unknown){
tmp<-rep(0,na)
tmp[which(A==g[i,1])]<-1
tmp[which(A==g[i,2])]<-1
D[i,which(tmp==1)]<-1
D[i,which(tmp==0)]<-(-1)
H[i,1,which(tmp==0)]<-(-1)
H[i,2,which(tmp==0)]<-(-1)
}
}
loop<-TRUE
while(loop){
tmpH<-H
tmpD<-D
for(i in 1:ns){
if(p[i,2]!=0){
H[i,1,which(D[p[i,2],]==-1)]<-(-1)
if(length(which(D[p[i,2],]>=0))==1){
H[i,1,which(D[p[i,2],]==1)]<-1
H[i,1,which(D[p[i,2],]!=1)]<-(-1)
}
}
if(length(which(H[i,1,]==-1))==(na-1))H[i,1,which(H[i,1,]>(-1))]<-1
if(length(which(H[i,1,]==1))==1)H[i,1,which(H[i,1,]!=1)]<--1
D[i,which(H[i,1,]==1)]<-1
if(p[i,3]!=0){
H[i,2,which(D[p[i,3],]==-1)]<-(-1)
if(length(which(D[p[i,3],]>=0))==1){
H[i,2,which(D[p[i,3],]==1)]<-1
H[i,2,which(D[p[i,3],]!=1)]<-(-1)
}
}
if(length(which(H[i,2,]==-1))==(na-1))H[i,2,which(H[i,2,]>(-1))]<-1
if(length(which(H[i,2,]==1))==1)H[i,2,which(H[i,2,]!=1)]<--1
D[i,which(H[i,2,]==1)]<-1
H[i,1,which(((D[i,]==1) * (H[i,2,]==-1))==1)]<-1
H[i,2,which(((D[i,]==1) * (H[i,1,]==-1))==1)]<-1
D[p[i,2],which(H[i,1,]==1)]<-1
D[p[i,3],which(H[i,2,]==1)]<-1
if(length(which(D[i,]==1))==2)D[i,which(D[i,]!=1)]<-(-1)
for(i in 1:ns){
D[i,which((H[i,1,]==-1) * (H[i,2,]==-1)==1)]<-(-1)
if(length(which(D[i,]==-1))>=(na-1))D[i,which(D[i,]>(-1))]<-1
}
}
if(isTRUE(all.equal(D,tmpD)) & isTRUE(all.equal(H,tmpH)))loop<-FALSE
}
dset<-dsetA<-list()
dtypeset<-dtypesetA<-list()
hset1<-hset2<-hset1A<-hset2A<-list()
for(i in 1:length(D[,1])){
tmpd1<-as.set(which(D[i,]==1))
tmpd0<-as.set(which(D[i,]==0))
tmpd1A<-as.set(A[which(D[i,]==1)])
tmpd0A<-as.set(A[which(D[i,]==0)])
if(set_is_empty(tmpd1)){
dset[[i]]<-set_combn(tmpd0,1) | set_combn(tmpd0,2)
dsetA[[i]]<-set_combn(tmpd0A,1) | set_combn(tmpd0A,2)
}else{
if(set_is_empty(tmpd0)){
dset[[i]]<-set(tmpd1)
dsetA[[i]]<-set(tmpd1A)
}else{
dset[[i]]<-dsetA[[i]]<-set()
tmpd01<-tmpd0 | tmpd1
for(j in tmpd01){
dset[[i]]<-dset[[i]] | set(tmpd1 | j)
}
tmpd01A<-tmpd0A | tmpd1A
for(j in tmpd01A){
dsetA[[i]]<-dsetA[[i]] | set(tmpd1A | j)
}
}
}
hset1[[i]]<-as.set(which(H[i,1,]>=0))
hset2[[i]]<-as.set(which(H[i,2,]>=0))
dtypeset[[i]]<-as.set(hset1[[i]]*hset2[[i]])
hset1A[[i]]<-as.set(A[which(H[i,1,]>=0)])
hset2A[[i]]<-as.set(A[which(H[i,2,]>=0)])
dtypesetA[[i]]<-as.set(hset1A[[i]]*hset2A[[i]])
}
for(i in 1:length(D[,1])){
tmpdset<-set()
for(j in dset[[i]]){
offsOK<-TRUE
oyajudge<-FALSE
oyanashi<-TRUE
for(k in 1:length(p[,1])){
if(p[k,2] == i | p[k,3] == i){
offsOKperchild<-FALSE
oyajudge<-TRUE
oyanashi<-FALSE
for(l in dset[[k]]){
if(!set_is_empty(j & l))offsOKperchild<-TRUE
}
if(!offsOKperchild)offsOK<-FALSE
}
}
hapsOK<-FALSE
if(!(set_is_empty(j & hset1[[i]])) & !(set_is_empty(j & hset2[[i]])) &
length(j & (hset1[[i]] | hset2[[i]]) )==length(j) )hapsOK<-TRUE
if(offsOK & hapsOK){
tmpdset<-tmpdset | set(j)
}
if(oyanashi & hapsOK){
oyajudge=TRUE
tmpdset<-tmpdset | set(j)
}
}
dset[[i]]<-tmpdset
}
for(i in 1:length(D[,1])){
tmpdset<-set()
for(j in dsetA[[i]]){
offsOK<-TRUE
oyajudge<-FALSE
oyanashi<-TRUE
for(k in 1:length(p[,1])){
if(p[k,2] == i | p[k,3] == i){
offsOKperchild<-FALSE
oyajudge<-TRUE
oyanashi<-FALSE
for(l in dsetA[[k]]){
if(!set_is_empty(j & l))offsOKperchild<-TRUE
}
if(!offsOKperchild)offsOK<-FALSE
}
}
hapsOK<-FALSE
if(!(set_is_empty(j & hset1A[[i]])) & !(set_is_empty(j & hset2A[[i]])) &
length(j & (hset1A[[i]] | hset2A[[i]]) )==length(j) )hapsOK<-TRUE
if(offsOK & hapsOK){
tmpdset<-tmpdset | set(j)
}
if(oyanashi & hapsOK){
oyajudge=TRUE
tmpdset<-tmpdset | set(j)
}
}
dsetA[[i]]<-tmpdset
}
dlist<-dlistA<-list()
for(i in 1:length(dset)){
cnt<-1
dlist[[i]]<-list()
for(j in dset[[i]]){
dlist[[i]][[cnt]]<-as.set(j)
cnt<-cnt+1
}
}
for(i in 1:length(dsetA)){
cnt<-1
dlistA[[i]]<-list()
for(j in dsetA[[i]]){
dlistA[[i]][[cnt]]<-as.set(j)
cnt<-cnt+1
}
}
list(D=D,H=H,dlist=dlist,dlistA=dlistA,dset=dset,dsetA=dsetA,dtypeset=dtypeset,dtypesetA=dtypesetA,
hset1=hset1,hset2=hset2,hset1A=hset1A,hset2A=hset2A)
}
LDZout<-LimitDiplotypeZ(p,g,A)