ディプロタイプを観測するということ
今、全部で人いるとする。染色体ハプロイドは
セットある。1つの2アレル型SNPについて着目すると、2種類のアレル数
は
を満足する。他方、2アレルが作る3ジェノタイプの人数
は
を満足する。
この分配方式を一般的に定義しなおすと次のようになる。
N個の観測単位(個人)がある。
観測単位は、同数の最小単位の実体(アレル)からなる(SNPの場合は、
)。実体総数は
個ある。
観測単位は、種類にわけれれ(SNPの場合は
)、
を満足する。
観測個体が最小単位実体を持つ、そのパターン(SNPの場合はジェノタイプ)は、ある(SNPの場合は、
で、ジェノタイプは
タイプ)。パターンごとの人数を
,
とすると、
を満足する
最小単位実体を中心にNxTテーブル(最小単位実体テーブル)を作ると以下のようになる。
| アレル1 | アレル2 | ... | アレルT | 合算 |
|---|---|---|---|---|
| k | 0 | ... | 0 | k |
| k | 0 | ... | 0 | k |
| k-1 | 1 | ... | 0 | k |
| k-1 | 0 | ... | 1 | k |
| k-2 | 2 | ... | 0 | k |
| k-2 | 1 | ... | 1 | k |
| 1 | 1 | ... | k-2 | k |
| 0 | 2 | ... | 0 | k |
| ... | ... | ... | ... | ... |
| N_1 | N_2 | ... | N_T | kN |
ここで、各個人に対応する行を構成する個の数値の組は、観測個体が持つ最小単位実体の持ち方のパターンに相当するから、この表において、
ずつ、同一の行がある。このパターンごとの
個の値を、
,
,
とする。それらについて、観測個体数に着目してテーブル(観測個体テーブル)を作成すると、1xXの表になる。
| パターン1 | パターン2 | ... | パターンX | 合算 |
|---|---|---|---|---|
| N_{p,1} | N_{p,2} | ... | N_{p,X} | N |
最小単位実体テーブルについて、その観測確率をその周辺度数から求めるには、
ここで、観測個体のパターンが同じ個体について、区別しないこととすると、観測個体テーブルを観測するような確率は
と表せる。
この式は、HWEの正確検定で用いる、あるアレルの観測本数を前提としたときの、ジェノタイプ数の観測確率に相当している。
もし、観測個体について、[texC]種類のカテゴリにわけるとする(ケース・コントロールの場合は)と、その分割表が
| パターン1 | パターン2 | ... | パターンX | 合算 |
|---|---|---|---|---|
| m_{1,1} | m_{1,2} | ... | m_{1,X} | m_{1,*} |
| m_{2,1} | m_{2,2} | ... | m_{2,X} | m_{2,*} |
| ... | ... | ... | ... | ... |
| m_{C,1} | m_{C,2} | ... | m_{C,X} | m_{C,*} |
| N_{p,1} | N_{p,2} | ... | N_{p,X} | N |
これは、
とも書ける。
これについての検算用の雑なjavaソースはこちら
public class generalExact {
/*
* kNの実体がT種類に分けられており、
* それがk個ずつに分配され、
* さらに、それが、
* Cカテゴリに分かれているような分配形式である
* SNPでケースコントロールの場合は
* T=2 C=2である
* kはディプロイドなら2
* dはTxNの表である
*/
public int k;//1人あたりの染色体本数
public int N;//人数
public int T;//アレル種類数
public int[] numT;//アレル別本数
public int C;
public int[] numC;//カテゴリ別人数
public int GenType;//genotype数
public int[] numGenType;//genotype別人数
public int[][] table;//2x3
public int kshinmax;
public int[][] tableT;//2x2
//public double[] serialLog;
public generalExact(int k_,int[][] d,int[] phen,int C_,double[] serialLog){
k=k_;
N=d.length;
//serialLog = serialLog_;
T=d[0].length;
numT = new int[T];
GenType=Fisher.combinseriallog(k+T-1,T-1,serialLog);
C=C_;
numC = new int[C];
kshinmax=(int)Math.pow((double)(k+1),(double)(T));
//System.out.print("kshinmax="+kshinmax+"\n");
table = new int[C][kshinmax];
tableT = new int[C][T];
numGenType = new int[kshinmax];
for(int i=0;i<d.length;i++){
int kshinnum=0;
for(int j=0;j<d[i].length;j++){
numT[j]+=d[i][j];
tableT[phen[i]][j]+=d[i][j];
int tmp=(int)Math.pow((double)(k+1),(double)(j));
//System.out.println("keta="+tmp);
//System.out.println("d[i][j]="+d[i][j]);
kshinnum+=d[i][j]*tmp;
}
//System.out.println("kshinnum\t"+kshinnum);
table[phen[i]][kshinnum]++;
numGenType[kshinnum]++;
numC[phen[i]]++;
}
}
public generalExact(int k_,int[][] d,int[] phen,int C_){
k=k_;
N=d.length;
double[] serialLog = Fisher.serialLogfact(N*k);
generalExact gE = new generalExact(k,d,phen,C_,serialLog);
T=gE.T;
numT = new int[T];
//GenType=Fisher.combinseriallog(k+T-1,T-1,serialLog);
C=C_;
numC = gE.numC;
//new int[C];
kshinmax=gE.kshinmax;
//kshinmax=(int)Math.pow((double)(k+1),(double)(T));
//System.out.print("kshinmax="+kshinmax+"\n");
//table = new int[C][kshinmax];
table = gE.table;
tableT = gE.tableT;
//tableT = new int[C][T];
numGenType = gE.numGenType;
//numGenType = new int[kshinmax];
/*
for(int i=0;i<d.length;i++){
int kshinnum=0;
for(int j=0;j<d[i].length;j++){
numT[j]+=d[i][j];
tableT[phen[i]][j]+=d[i][j];
int tmp=(int)Math.pow((double)(k+1),(double)(j));
//System.out.println("keta="+tmp);
//System.out.println("d[i][j]="+d[i][j]);
kshinnum+=d[i][j]*tmp;
}
//System.out.println("kshinnum\t"+kshinnum);
table[phen[i]][kshinnum]++;
numGenType[kshinnum]++;
numC[phen[i]]++;
}
*/
}
public double[] probForK2(double[] s){
double[] ret = new double[3];
double judgeTableT=0;
for(int i=0;i<tableT.length;i++){
for(int j=0;j<tableT[i].length;j++){
judgeTableT+=s[tableT[i][j]];
}
}
System.out.println("judgeTableT=\t"+judgeTableT);
/*
* k=2,T=2,C=2である
*/
if(k!=2 || T!=2 || C!=2){
return ret;
}
/*
* ExactHWEはとりうるすべての3ジェノタイプ数を網羅してくれる
* numGenType[2],[4],[6]に値が格納されている
*/
boolean evenodd = true;
if(numGenType[4]%2==1)evenodd=false;
int minhetero=0;
int maxhetero=Math.min(numT[0], numT[1]);
int numPattern=maxhetero-minhetero+1;
double[] Qs = new double[numPattern];
double sumQ=0;
if(evenodd){
minhetero=0;
}else if(!evenodd){
minhetero=1;
}
int here = N+1;
for(int i=minhetero;i<=maxhetero;i=i+2){
//System.out.println("i="+i);
int g1 = (numT[0]-i)/2;
int g2 = i;
int g3 = N-(numT[0]+i)/2;
//System.out.println("3types="+g1 +" "+g2+" "+g3);
//int hetero = allele-i*2;
//if(hetero<0){
//continue;
//}
//int neghomo = sum-i-hetero;
//if(neghomo<0){
//continue;
//}
//System.out.println("i hetero neghomo " + i + " " + hetero + " " + neghomo);
double combin = (s[N]+s[numT[0]]+s[numT[1]])
-(s[g2] + s[g1] + s[g3] +s[N*2]);
//System.out.println("combin "+ combin);
Qs[i]=Math.exp(combin + i * Math.log(2) );
sumQ+=Qs[i];
System.out.print("i=\t"+i +"\tthreeGenotypes\t"+g1+"\t"+g2+"\t"+g3+"\t\tHWE_P_component\t"+Qs[i]+"\n");
//double P1 = Math.exp(combin + i * Math.log(2) );
//System.out.println("P0="+P0+" P1="+P1);
/*
* 3ジェノタイプのとり方ごとに計算する
* この3ジェノタイプの分布において、
* アレルのケースコントロール分布が同一な2x3表を作れれば作る
* 作れなければ
*/
int[] margL = numC;
int[] margC = {g1,g2,g3};
int N2=N*2;
double[] tmp = extPs(margL,margC,N2,tableT,judgeTableT,s);
ret[0]+=tmp[0]*Qs[i];
ret[1]+=tmp[1]*Qs[i];
System.out.println("extPs=\t"+tmp[0]+"\t"+tmp[1]);
}
System.out.println("Qsum=\t"+sumQ);
System.out.print("P=\t"+ret[0]+"\t"+ret[1]+"\n");
return ret;
}
public double[] extPs(int[] margL,int[] margC,int sum,int[][] twoBYtwo,double org,double[] logFact){
double[] ret = {0,0};
int[][] da = new int[2][3];
//{{margL[0],0,0},{margL[1],0,0}};
da[0][0]=Math.min(margL[0], margC[0]);
da[1][0]=margC[0]-da[0][0];
int tmpMargL = margL[0]-da[0][0];
da[0][1]=Math.min(tmpMargL,margC[1]);
da[1][1]=margC[1]-da[0][1];
da[0][2]=tmpMargL-da[0][1];
da[1][2]=margC[2]-da[0][2];
//System.out.println("dummyGenos\n"+da[0][0]+"\t"+da[0][1]+"\t"+da[0][2]+"\n"+da[1][0]+"\t"+da[1][1]+"\t"+da[1][2]);
//int[][] twoBYtwo = {{da[0][0]*2+da[0][1],da[0][1]+2*da[0][2]},{da[1][0]*2+da[1][1],da[1][1]+2*da[1][2]}};
//System.out.println("twoBYtwo\n"+twoBYtwo[0][0]+"\t"+twoBYtwo[0][1]+"\t"+twoBYtwo[1][0]+"\t"+twoBYtwo[1][1]);
int[] Lmarg = {twoBYtwo[0][0]+twoBYtwo[0][1],twoBYtwo[1][0]+twoBYtwo[1][1]};
int[] Cmarg = {twoBYtwo[0][0]+twoBYtwo[1][0],twoBYtwo[0][1]+twoBYtwo[1][1]};
//int sum = Lmarg[0]+Lmarg[1];
/*
double[][] exp = {{(double)(Lmarg[0]*Cmarg[0])/sum,(double)(Lmarg[0]*Cmarg[1])/sum},
{(double)(Lmarg[1]*Cmarg[0])/sum,(double)(Lmarg[1]*Cmarg[1])/sum}};
*/
int min=Math.max(0, Cmarg[0]-Lmarg[1]);
min = Math.max(min, Lmarg[0]-Cmarg[1]);
int max=Math.min(Lmarg[0], Cmarg[0]);
//System.out.println("min="+min);
//System.out.println("max="+max);
//double[] judge = new double[max-min+1];
int ceilMinSide=-1;
int floorMaxSide=0;
int extORint=0;
int checkCounter=0;
//double org = logFact[twoBYtwo[0][0]]+logFact[twoBYtwo[0][1]]+logFact[twoBYtwo[1][0]]+logFact[twoBYtwo[1][1]];
int[] orgfour = {twoBYtwo[0][0],twoBYtwo[0][1],twoBYtwo[1][0],twoBYtwo[1][1]};
//int[] orgfour = {tableT[0][0],tableT[0][1],table[1][0],tableT[1][1]};
StatUtils.MiscUtil.bublSort(orgfour);
//System.out.println("org="+org);
//if(twoBYtwo[0][0]>=exp[0][0]){
ceilMinSide=min;
for(int i=min;i<=max;i++){
//System.out.println("i="+i);
checkCounter++;
int[] tmp = {i,Lmarg[0]-i,Cmarg[0]-i,Lmarg[1]-Cmarg[0]+i};
int[] sorttmp = StatUtils.MiscUtil.DeepCopyInt1(tmp);
StatUtils.MiscUtil.bublSort(sorttmp);
boolean ident = StatUtils.MiscUtil.IdenticalIntList(orgfour, sorttmp);
//System.out.println("ident="+ident);
if(ident){
//System.out.println("i="+i);
ceilMinSide=i;
//System.out.println("$$$$$$"+tmp[0]+" "+tmp[1]+" "+tmp[2]+ " "+tmp[3]);
double tmpval = Fisher.Prob2x3sfor2x2X(da,tmp,logFact);
ret[0] += tmpval;
ret[1] += tmpval;
//System.out.println("tmpval=\t"+tmpval);
}else{
double tmplog = logFact[tmp[0]]+logFact[tmp[1]]+logFact[tmp[2]]+logFact[tmp[3]];
//System.out.println("tmporg="+tmplog);
if(tmplog>=org){
//System.out.println("i="+i);
ceilMinSide=i;
double tmpval = Fisher.Prob2x3sfor2x2X(da,tmp,logFact);
ret[0] += tmpval;
ret[1] += tmpval;
//System.out.println("tmpval=\t"+tmpval);
}else{
ceilMinSide=i;
/*
for(int j=min;j<i;j++){
System.out.println("j="+j);
}
*/
double tmpval = Fisher.Prob2x3sfor2x2X(da,tmp,logFact);
ret[1] += tmpval;
//ret += tmpval;
//System.out.println("tmpval=\t"+tmpval);
//break;
}
}
}
floorMaxSide = max;
//System.out.println("max="+max+"ceilMinSide="+ceilMinSide);
for(int i=max;i>ceilMinSide;i--){
checkCounter++;
int[] tmp = {i,Lmarg[0]-i,Cmarg[0]-i,Lmarg[1]-Cmarg[0]+i};
int[] sorttmp = StatUtils.MiscUtil.DeepCopyInt1(tmp);
StatUtils.MiscUtil.bublSort(sorttmp);
boolean ident = StatUtils.MiscUtil.IdenticalIntList(orgfour, sorttmp);
//System.out.println("ident="+ident);
if(ident){
//System.out.println("i="+i);
floorMaxSide=i;
//System.out.println("$$$$$$"+tmp[0]+" "+tmp[1]+" "+tmp[2]+ " "+tmp[3]);
//ret += Fisher.Prob2x3sfor2x2X(da,tmp,logFact);
double tmpval = Fisher.Prob2x3sfor2x2X(da,tmp,logFact);
ret[0] += tmpval;
ret[1] += tmpval;
//System.out.println("tmpval=\t"+tmpval);
}else{
double tmplog = logFact[tmp[0]]+logFact[tmp[1]]+logFact[tmp[2]]+logFact[tmp[3]];
//System.out.println("tmporg="+tmplog);
if(tmplog>org){
//System.out.println("i="+i);
//ret += Fisher.Prob2x3sfor2x2X(da,tmp,logFact);
double tmpval = Fisher.Prob2x3sfor2x2X(da,tmp,logFact);
ret[0] += tmpval;
ret[1] += tmpval;
//System.out.println("tmpval=\t"+tmpval);
}else{
floorMaxSide=i;
/*
for(int j=max;j>i;j--){
System.out.println("j="+j);
}
*/
double tmpval = Fisher.Prob2x3sfor2x2X(da,tmp,logFact);
ret[1] += tmpval;
//ret += tmpval;
//System.out.println("tmpval=\t"+tmpval);
//break;
}
}
}
return ret;
}
public static int sumline(int[] l){
int ret =0;
for(int i=0;i<l.length;i++){
ret += l[i];
}
return ret;
}
public String stringGeneralExact(String sep1,String sep2){
String ret = "";
ret += "No.samples"+sep1 + N+sep2;
ret += "No.objectsPerSample"+sep1+k+sep2;
ret += "No.alleles"+sep1+T+sep2;
ret += "No.categories"+sep1+C+sep2;
ret += "No.genotypes"+sep1+GenType+sep2;
ret += "No.objectsPerAllele"+sep2;
for(int i=0;i<numT.length;i++){
ret += numT[i]+sep1;
}
ret += sep2;
ret += "No.samplesPerCategory"+sep2;
for(int i=0;i<numC.length;i++){
ret += numC[i]+sep1;
}
ret += sep2;
ret += "No.samplesPerGenotype"+sep2;
for(int i=0;i<kshinmax;i++){
ret += numGenType[i]+sep1;
}
ret += sep2;
ret += "No.samplesPerCategoryPerGenotype"+sep2;
for(int j=0;j<table.length;j++){
for(int i=0;i<table[j].length;i++){
ret +=table[j][i]+sep1;
}
ret += sep2;
}
ret += "No.objectsPerCategoryPerAllele"+sep2;
for(int j=0;j<tableT.length;j++){
for(int i=0;i<tableT[j].length;i++){
ret +=tableT[j][i]+sep1;
}
ret += sep2;
}
return ret;
}
public void printGeneralExact(String sep1,String sep2){
String ret = stringGeneralExact(sep1,sep2);
System.out.print(ret);
}
/*
* @param args
*/
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
int k=2;
//int[] phenotype = {0,0,1,1};
int[][] fix = {{10,20,10},{70,10,0}};
int sumfix=0;
for(int i=0;i<fix.length;i++){
for(int j=0;j<fix[i].length;j++){
sumfix+=fix[i][j];
}
}
int[][] data2 = new int[sumfix][2];
int[] phenotype2 = new int[sumfix];
int counter=0;
for(int i=0;i<fix.length;i++){
for(int j=0;j<fix[i].length;j++){
for(int l=0;l<fix[i][j];l++){
phenotype2[counter]=i;
if(j==0){
data2[counter][0]=2;
data2[counter][1]=0;
}else if(j==1){
data2[counter][0]=1;
data2[counter][1]=1;
}else{
data2[counter][0]=0;
data2[counter][1]=2;
}
counter++;
}
}
}
int N = 8;
int T = 2;
int [][] data = new int[N][T];
int[] phenotype = new int[N];
//int[][] data = {{2,0,0,0},{1,0,1,0},{0,0,1,1},{0,2,0,0}};
int C=2;
int seed = (int)(Math.random()*100000);
//System.out.println("seed="+seed);
Utils.MersenneTwisterFast mz = new Utils.MersenneTwisterFast(seed);
double af = 0.03;
for(int i=0;i<N;i++){
int tmpphen = mz.nextInt(C);
phenotype[i]=tmpphen;
//System.out.println("tmpphen\t"+tmpphen);
for(int j=0;j<k;j++){
int tmp = mz.nextInt(T);
double tmpd = mz.nextDouble();
double tmpr = mz.nextDouble();
if(tmpr<0.95){
// System.out.println("tmpd="+tmpd);
if(tmpd<af){
tmp=0;
}else{
tmp=1;
}
}else{
tmp=0;
}
//System.out.println("tmp\t"+tmp);
data[i][tmp]++;
}
}
//int[][] data2={{5,10,5},{10,5,5}};
//double[] serialLog = Fisher.serialLogfact(N*2);
double[] serialLog = Fisher.serialLogfact(sumfix*2);
//int[] phenotype2={0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1};
//generalExact gE = new generalExact(k,data,phenotype,C,serialLog);
generalExact gE = new generalExact(k,data2,phenotype2,C,serialLog);
gE.printGeneralExact("\t","\n");
gE.probForK2(serialLog);
int[][] twoBYthree={{gE.table[0][2],gE.table[0][4],gE.table[0][6]},
{gE.table[1][2],gE.table[1][4],gE.table[1][6]}};
int[] testType=new int[18];
for(int i=0;i<testType.length;i++){
testType[i]=i;
}
double[] singleSNPtest = BBPPhenotypeVector3GC.SingleSNPtest4.PforSelectedTestsOriginal2(twoBYthree,serialLog,testType);
System.out.print("2x2Fisher\t"+singleSNPtest[2]+"\t2x2Chi\t"+singleSNPtest[3]+"\tTrendExact\t"+singleSNPtest[10]+"\tTrend\t"+singleSNPtest[9]+"\tHWE\t"+singleSNPtest[17]);
//for(int i=0;i<singleSNPtest.length;i++){
//System.out.print(singleSNPtest[i]+"\t");
//}
/*
System.out.println("k="+gE.k);
System.out.println("T="+gE.T);
System.out.println("gentype="+gE.GenType);
for(int i=0;i<gE.table.length;i++){
for(int j=0;j<gE.table[i].length;j++){
System.out.print(gE.table[i][j]+"\t");
}
System.out.print("\n");
}
*/
}
}
>||
public static double Prob2x3sfor2x2X(int[][] da, int[] four,double[] logFact){
double ret=0;
//System.out.println("&&&&&&&&");
//System.out.println("four="+four[0]+" "+four[1]+" "+ four[2]+ " "+four[3]);
int[] Lmarg={da[0][0]+da[0][1]+da[0][2],da[1][0]+da[1][1]+da[1][2]};
int[] Cmarg={da[0][0]+da[1][0],da[0][1]+da[1][1],da[0][2]+da[1][2]};
//System.out.println("Lmarg="+Lmarg[0]+" "+Lmarg[1]);
//System.out.println("Cmarg="+Cmarg[0]+" "+Cmarg[1]+" "+Cmarg[2]);
double constant = -logFact[Lmarg[0]+Lmarg[1]]+logFact[Lmarg[0]]+logFact[Lmarg[1]]
+logFact[Cmarg[0]]+logFact[Cmarg[1]]+logFact[Cmarg[2]];
int[][] tmpda = new int[2][3];
int max01 = Cmarg[1]-(Lmarg[1]-Cmarg[0]-Cmarg[2]);
int min02 = Cmarg[2]-Lmarg[1];
int min = Math.max(0, (int)((four[0]-max01)/2));
int max = Math.min((int)(four[0]/2), Cmarg[0]);
//System.out.println("min="+min);
//System.out.println("max="+max);
for(int i=min;i<=max;i++){
tmpda[0][0]=i;
tmpda[0][1]=(four[0]-2*tmpda[0][0]);
tmpda[0][2]=Lmarg[0]-tmpda[0][0]-tmpda[0][1];
if(tmpda[0][2]>=0){
tmpda[1][1]=Cmarg[1]-tmpda[0][1];
if(tmpda[1][1]>=0){
tmpda[1][0]=Cmarg[0]-tmpda[0][0];
if(tmpda[1][0]>=0){
tmpda[1][2]=Cmarg[2]-tmpda[0][2];
if(tmpda[1][2]>=0){
String st="!!##\t";
for(int j=0;j<tmpda.length;j++){
for(int k=0;k<tmpda[j].length;k++){
st += tmpda[j][k]+"\t";
}
}
//System.out.print(st);
double variableLog = constant-(logFact[tmpda[0][0]]+logFact[tmpda[0][1]]+logFact[tmpda[0][2]]+
logFact[tmpda[1][0]]+logFact[tmpda[1][1]]+logFact[tmpda[1][2]]);
//System.out.println("variablelog="+variableLog);
double tmpvar=Math.exp(variableLog);
//System.out.print(tmpvar+"\n");
ret += tmpvar;
//System.out.println(st + "\t"+Math.exp(variableLog));
}
}
}
}
}
return ret;
}