awk を使ってターミナル上で必要な部分の列和を計算する

SNP とかなんでもいいのだが、行列データがあって、ある列のデータのうち条件をみたすものだけを抽出して、和を取りたい。
それをR とかPython を使わずに、シェルというかawk で完結したいのだが、という悩みを同僚が言ってきたのでやってみた。
 
一発でsum みたいな関数で和が出るわけではないので、必要な列を取る > 条件分岐する > increment で足す > 最後にprint する、という感じでやればこんな感じ。
awk で変数を引数にとるには -v オプションを使えばいいので、シェル芸人できる。
サンプルデータの作成にはR でワンライナーを使った。

R -q -e 'write.table(matrix(ceiling(runif(10*20, 1, 1000)), 20), "testmat.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)'
cat testmat.txt
awk '{if($2 > 800) total = total + $2};END{print total}' testmat.txt

サンプルデータはこんな感じで

283 362 409 13 703 991 907 765 932 947
790 141 739 100 356 795 169 650 635 747
267 531 53 891 587 273 821 164 124 548
465 332 425 431 377 761 125 316 901 495
636 139 424 736 777 152 793 143 282 908
367 335 568 468 377 478 79 38 471 395
12 773 929 556 418 503 539 305 210 348
265 584 193 211 184 72 346 967 343 212
981 727 444 324 300 511 773 549 453 607
37 87 892 808 538 413 837 746 471 51
798 488 798 810 952 682 74 38 826 21
576 985 498 788 571 671 683 930 39 335
278 413 154 409 413 155 807 523 513 545
104 30 257 455 979 232 415 935 174 258
962 993 59 291 8 809 243 793 430 47
782 17 465 925 483 109 740 250 782 804
578 51 265 666 40 991 211 476 964 353
110 730 443 805 580 373 498 276 832 524
438 188 327 638 260 664 478 810 256 59
888 387 781 425 747 905 783 472 824 274

全然イケてないけどR のワンライナーで検算すれば

R -q -e 'sum(read.table("testmat.txt")[read.table("testmat.txt")[,2]>800,2])'

Python で書けば

python -c "import numpy as np; a=np.loadtxt('testmat.txt'); print(np.sum(a[np.where(a[:,1]>800),1])) "

OmicCircos

MikuHatsune2017-09-08

読んだ。
Cancer Inform. 2014 Jan 16;13:13-20.
 
オミックス研究では、各染色体でのCNVや遺伝子発現状態、各種統計量の定量値や分布などをずらずらっと描きたいが、横に長く描くといけてないと誰かが思ったのだろうか、丸く描くやり方がある。
これをcircos plot と呼ぶが、5年くらい前にこの図を論文で見たときに描いてみたいとおもったときに、Rでよさそうなパッケージがなかったような気がするが、出来てた。
 

library(OmicCircos);
options(stringsAsFactors = FALSE);

data("TCGA.PAM50_genefu_hg18");
data("TCGA.BC.fus");
data("TCGA.BC.cnv.2k.60");
data("TCGA.BC.gene.exp.2k.60");
data("TCGA.BC.sample60");
data("TCGA.BC_Her2_cnv_exp");

#transform p-value
pvalue <- -1 * log10(TCGA.BC_Her2_cnv_exp[,5]);
pvalue <- cbind(TCGA.BC_Her2_cnv_exp[,c(1:3)], pvalue);

Her2.i <- which(TCGA.BC.sample60[,2] == "Her2");
Her2.n <- TCGA.BC.sample60[Her2.i,1];

Her2.j <- which(colnames(TCGA.BC.cnv.2k.60) %in% Her2.n);
cnv    <- TCGA.BC.cnv.2k.60[,c(1:3,Her2.j)]; 
cnv.m  <- cnv[,c(4:ncol(cnv))];
cnv.m[cnv.m >  2] <- 2;
cnv.m[cnv.m < -2] <- -2;
cnv <- cbind(cnv[,1:3], cnv.m);

Her2.j   <- which(colnames(TCGA.BC.gene.exp.2k.60) %in% Her2.n);
gene.exp <- TCGA.BC.gene.exp.2k.60[,c(1:3,Her2.j)]; 

colors <- rainbow(10, alpha=0.5);

#png("OmicCircos4vignette10.png", 600, 600);
par(mar=c(2, 2, 2, 2));

plot(c(1,800), c(1,800), type="n", axes=FALSE, xlab="", ylab="", main="");

zoom <- c(1, 22, 939245.5, 154143883, 0, 180);
circos(R=400, cir="hg18", W=4,   type="chr", print.chr.lab=TRUE, scale=TRUE, zoom=zoom);
circos(R=300, cir="hg18", W=100, mapping=gene.exp, col.v=4,  type="heatmap2", cluster=TRUE, col.bar=TRUE, lwd=0.01, zoom=zoom);
circos(R=220, cir="hg18", W=80,  mapping=cnv,      col.v=4,   type="ml3", B=FALSE, lwd=1, cutoff=0, zoom=zoom);
circos(R=140, cir="hg18", W=80,  mapping=pvalue,   col.v=4,    type="l",   B=TRUE, lwd=1, col=colors[1], zoom=zoom);
circos(R=130, cir="hg18", W=10,  mapping=TCGA.BC.fus, type="link", lwd=2, zoom=zoom);

## zoom in links by using the hightlight functions 
## highlight
the.col1=rainbow(10, alpha=0.5)[1];

highlight <- c(140, 400, 11, 282412.5, 11, 133770314.5, the.col1, the.col1);
circos(R=110, cir="hg18", W=40, mapping=highlight, type="hl", lwd=2, zoom=zoom);
the.col2=rainbow(10, alpha=0.5)[6];
highlight <- c(140, 400, 17, 739525, 17, 78385909, the.col2, the.col2);
circos(R=110, cir="hg18", W=40, mapping=highlight, type="hl", lwd=2, zoom=zoom);
## highlight link
highlight.link1 <- c(400, 400, 140, 376.8544, 384.0021, 450, 540.5);
circos(cir="hg18", mapping=highlight.link1, type="highlight.link", col=the.col1, lwd=1);
highlight.link2 <- c(400, 400, 140, 419.1154, 423.3032, 543, 627);
circos(cir="hg18", mapping=highlight.link2, type="highlight.link", col=the.col2, lwd=1);

## zoom in chromosome 11
zoom <- c(11, 11, 282412.5, 133770314.5, 180, 270);
circos(R=400, cir="hg18", W=4,   type="chr", print.chr.lab=TRUE, scale=TRUE, zoom=zoom);
circos(R=300, cir="hg18", W=100, mapping=gene.exp, col.v=4,  type="heatmap2", cluster=TRUE, lwd=0.01, zoom=zoom);
circos(R=220, cir="hg18", W=80,  mapping=cnv,      col.v=4,   type="ml3", B=FALSE, lwd=1, cutoff=0, zoom=zoom);
circos(R=140, cir="hg18", W=80,  mapping=pvalue,   col.v=4,    type="l",   B=TRUE, lwd=1, col=colors[1], zoom=zoom);

## zoom in chromosome 17
zoom <- c(17, 17, 739525, 78385909, 274, 356);
circos(R=400, cir="hg18", W=4,   type="chr", print.chr.lab=TRUE, scale=TRUE, zoom=zoom);
circos(R=300, cir="hg18", W=100, mapping=gene.exp, col.v=4,  type="heatmap2", cluster=TRUE, lwd=0.01, zoom=zoom);
circos(R=220, cir="hg18", W=80,  mapping=cnv,      col.v=4,   type="ml3", B=FALSE, lwd=1, cutoff=0, zoom=zoom);
circos(R=140, cir="hg18", W=80,  mapping=pvalue,   col.v=4,    type="l",   B=TRUE, lwd=1, col=colors[1], zoom=zoom);

#dev.off()


 

library(OmicCircos);
options(stringsAsFactors = FALSE);

data("TCGA.BC.fus");
data("TCGA.BC.cnv.2k.60");
data("TCGA.BC.gene.exp.2k.60");
data("TCGA.BC.sample60");

## gene expression data for PCA
exp.m <- TCGA.BC.gene.exp.2k.60[,c(4:ncol(TCGA.BC.gene.exp.2k.60))];

cnv   <- TCGA.BC.cnv.2k.60;

## PCA
type.n  <- unique(TCGA.BC.sample60[,2]);
colors  <- rainbow(length(type.n), alpha=0.5);

pca.col <- rep(NA, nrow(TCGA.BC.sample60));
for (i in 1:length(type.n)){
  n   <- type.n[i];
  n.i <- which(TCGA.BC.sample60[,2] == n);
  n.n <- TCGA.BC.sample60[n.i,1];
  g.i <- which(colnames(exp.m) %in% n.n);
  pca.col[g.i] <- colors[i];
}

exp.m   <- na.omit(exp.m);
pca.out <- prcomp(t(exp.m), scale = TRUE);

## subtype cnv
cnv.i <- c();
for (i in 1:length(type.n)){
  n     <- type.n[i];
  n.i   <- which(TCGA.BC.sample60[,2] == n);
  n.n   <- TCGA.BC.sample60[n.i,1];
  cnv.i <- which(colnames(cnv) %in% n.n);
}

## main
#png("OmicCircos4vignette8.png", 600, 600);
par(mar=c(5, 5, 5, 5));

plot(c(1,800), c(1,800), type="n", axes=FALSE, xlab="", ylab="", main="");

legend(680,800, c("Basal","Her2","LumA","LumB"), pch=19, col=colors[c(2,4,1,3)], cex=0.5, 
     title ="Gene Expression (PCA)", box.col="white");

legend(5,800, c("1 Basal", "2 Her2", "3 LumA", "4 LumB", "(center)"), cex=0.5, 
     title ="CNV (OmicCircos)", box.col="white");

circos(xc=400, yc=400, R=390, cir="hg18", W=4,  type="chr", print.chr.lab=TRUE, scale=TRUE);
R.v <- 330;
for (i in 1:length(type.n)){
  n     <- type.n[i];
  n.i   <- which(TCGA.BC.sample60[,2] == n);
  n.n   <- TCGA.BC.sample60[n.i,1];
  cnv.i <- which(colnames(cnv) %in% n.n);
  cnv.v <- cnv[,cnv.i];
  cnv.v[cnv.v > 2]  <- 2;
  cnv.v[cnv.v < -2] <- -2;
  cnv.m <- cbind(cnv[,c(1:3)], cnv.v);
  if (i%%2==1){
    circos(xc=400, yc=400, R=R.v, cir="hg18", W=60, mapping=cnv.m, col.v=4,  
           type="ml3", B=TRUE, lwd=1, cutoff=0, scale=TRUE);
  } else {
    circos(xc=400, yc=400, R=R.v, cir="hg18", W=60, mapping=cnv.m, col.v=4,  
           type="ml3", B=FALSE, lwd=1, cutoff=0, scale=TRUE);
  }
  R.v <- R.v - 60;
}

points(pca.out$x[,1]*6+410, pca.out$x[,2]*6+400, pch=19, col=pca.col, cex=2);

#dev.off() 

EM アルゴリズムとベイズ

MikuHatsune2017-03-02

EM アルゴリズムベイズという話が出てきたので、やってみる。
題材はこちら
状況としては、ABOの血液型で、どんな血液型を持っているかは観測できるが、その血液型population を生み出したアレル頻度は一体どのようなものだろうか、これを推定したい、ということ。
EM アルゴリズムベイズも、観測できない潜在パラメータ\theta を、手持ちのデータからなんとかして推定しようという試み。
 
EM では適当にABO のアレル頻度P_a, P_b, P_o として、実際にABO 血液型を観測した人数に当てはめて、アレルの期待値を出して、それを更新して人数に当てはめてアレルの期待値を出して、…を繰り返す。
(ここで、ABO 血液型がどのように生じるかという遺伝学、分子生物学的な知識は既にあるものとし、ボンベイ型やシスAB 型みたいなレアなものは考えないとする。)
すると、リンクのような、A:B:AB:O=160:80:40:120のときに、アレル頻度をEM で求めると

dat <- c(A=160, B=80, AB=40, O=120)
N <- sum(dat)*2

# 初期値
pa <- 0.2
pb <- 0.2
po <- 1-pa-pb

ABO <- c(pa, pb, po)

niter <- 10
for(i in 1:niter){
  # E-step
  pA <- c(pa*(pa+po) / (pa*(pa+2*po)), 0, pa*pb/(2*pa*pb), 0)
  nA <- sum(pA * dat)

  pB <- c(0, pb*(pb+po)/(pb*(pb+2*po)), pa*pb/(2*pa*pb), 0)
  nB <- sum(pB * dat)

  nO <- sum(dat) - nA - nB
  # M-step
  pabo <- c(nA, nB, nO)/sum(dat)
  
  pa <- pabo[1]
  pb <- pabo[2]
  po <- pabo[3]

  ABO <- rbind(ABO, pabo)
}

matplot(ABO, type="l", lwd=3, lty=1, ylim=c(0, 1), xlab="iteration")
legend("topright", legend=c("A", "B", "O"), lty=1, col=1:3, lwd=3)

アルゴリズムの停止は、更新値がどれだけ更新されなくなったかという収束限界値をいれてもいいし、更新回数でもよい。
この場合ではほんの数回でほぼ収束する。

 
ベイズ的にやってみる。rstan でやるならば、アレルABO は足して1になるのでsimplex からサンプリングされ(dirichlet)、実際のABO の血液型は、そのアレル頻度から理論的(HWE)に推定されるA/B/AB/O 血液型の確率から非負の整数値がサンプリングされる(multinomial)とする。このとき、A/B/AB/O 血液型は足して1になる。というのは、普通に考えてそうだし、A/B/AB/O を生み出すABO アレルがそもそも足して1 なので計算上も勝手にそうなる。

library(rstan)
stanmodel <- '
data{
  int<lower=0> N[4];
}
parameters{
  simplex[3] pABO;
}
transformed parameters{
  simplex[4] p;
  p[1] <- pABO[1]*pABO[1] + 2*pABO[1]*pABO[3]; 
  p[2] <- pABO[2]^2 + 2*pABO[2]*pABO[3];
  p[3] <- 2*pABO[1]*pABO[2];
  p[4] <- pABO[3]^2;
}
model{
  N ~ multinomial(p);
}
'
m <- stan_model(model_code=stanmodel)
fit <- sampling(m, list(N=dat))
4 chains, each with iter=2000; warmup=1000; thin=1; 
post-warmup draws per chain=1000, total post-warmup draws=4000.

           mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
pABO[1]    0.29    0.00 0.02    0.26    0.28    0.29    0.30    0.33  3005    1
pABO[2]    0.16    0.00 0.01    0.14    0.15    0.16    0.17    0.19  2609    1
pABO[3]    0.54    0.00 0.02    0.50    0.53    0.54    0.56    0.58  2525    1
p[1]       0.40    0.00 0.02    0.36    0.39    0.40    0.42    0.45  3058    1
p[2]       0.20    0.00 0.02    0.17    0.19    0.20    0.22    0.24  2830    1
p[3]       0.10    0.00 0.01    0.08    0.09    0.10    0.10    0.11  2462    1
p[4]       0.30    0.00 0.02    0.25    0.28    0.30    0.31    0.34  2522    1
lp__    -516.70    0.03 1.06 -519.64 -517.09 -516.35 -515.96 -515.70  1139    1

実行結果は、EM の場合とほぼ一緒である。
実際にサンプリングされたABO アレル頻度の散布図である。上の推定結果からもわかるように、非常に狭い範囲で推定されている。図でもx+y+z=1 の平面上の極狭い部分にしか点が存在しない。
モデルとしてはかなりシンプルなので推定が楽だし、ベイズを使うとEM では初期値を(A,B,O)=(0.2,0.2,0.6) と選んだのがなぜそれを選んだの?(先行研究から選ぶもんだが) という疑問が拭えないので、ベイズで無情報分布でうまくいったのでいいことにする。
もちろん、EM でも初期値をディリクレ分布から適当に選びまくって推定して、どんな初期値でも同じような結果に収束する(今回はするだろうけど)ことを確認してもいいし、逆にベイズのほうでも、事前に先行研究から範囲が分かっていれば、ABO アレルのsimplex サンプリングに偏ったdirichlet 分布から発生されてもよいはず。

inheritance vector

読んだ。Am J Hum Genet. 1996 Jun; 58(6): 1323–1337.
 
inheritance vector というものがよくわからなかったのでLander-Green algorithm とともにいくつか検索。inheritance vector と何も考えずに検索するとプログラミングのinheritance が引っかかる。
Parametric and nonparametric linkage analysis: a unified multipoint approach.
http://csg.sph.umich.edu/abecasis/class/666.20.pdf
http://www.stat.berkeley.edu/~terry/Classes/s260.1998/Week8a/week8a/node13.html
Handling Marker-Marker Linkage Disequilibrium: Pedigree Analysis with Clustered Markers - ScienceDirect

http://lifesciencedb.mext.go.jp/result/analysis_technology.pdf
ランダー・グリーン アルゴリズム(1) - aggren0xの日記
ランダー・グリーン・アルゴリズム(6) - aggren0xの日記
2013-04-09 - aggren0xの日記

遺伝統計学の基礎―Rによる遺伝因子解析・遺伝子機能解析―

遺伝統計学の基礎―Rによる遺伝因子解析・遺伝子機能解析―

 
inheritance vector とは、家系内のある人の染色体が父親由来なのか母親由来なのかを\{0,1\} のバイナリで記述したベクトル。
まず、家系内で父母が確定していない人をfounder と呼ぶ。ヒトで言えば、founderf 人いるとき、アレルは2f 個ある。
家系内で父母が確定している人は、逆にnon-founder と呼ぶ。non-founder たちのアレルは、すべてfounder から由来している。inheritance vector はnon-foundern 人いるとき、長さ2n のベクトルである。i 番目の人について、家系図を左から右、上から下へ昇順に並べて記述したとき、
v=\{p_1,m_1,\dots,p_i,m_i,\dots,p_n,m_n\}
と定義される。
 
ネットで拾った画像で詳細を追ってみる。この家系図と遺伝子型は論文と同じである。
やりたいことは、あるlocus l のinheritance vector v_l があるときに、あるlocus のマーカーm_lを得る確率Pr(m_l|v_l) を求めることである。

 
これをdescent graph として記述する。descent graph は人ノードを2つのアレルに分解して、父方アレルと母方アレルの伝わり方でエッジを引いたものである。慣例的に左が父方由来、右が母方由来で書かれることが多い。

 
いま、親が不明のfounder は1-8番のノードの染色体で示される。これは、もともとF0世代の父母と、F1 世代の婿(11)と嫁(14)に相当する。
ここで、各アレルの伝わり方が矢印ですべてわかっているとすると、inheritance vector は、家系図を左から右、上から下の昇順にみていって、親が既知であるnon-founder の (12), (13), (21), (22), (23), (24)さんたちの各アレルについて
v=(1,1;0,0;1,1;1,1;1,1;0,0)
となる。この場合は、1が父方由来、0が母方由来、としている。

 
descent graph から、founder graph を作る。例えばF0 の(1) が持っている3番のアレルは、F1 の(12)に遺伝して、F2 の(22)に遺伝している。F1 の(11)が持っている1番のアレルは、F2 の(21)に遺伝している。アレル単位でみるとバラけているが、2つの染色体をもつとヒトになることを意識すれば、1番のアレルと3番のアレルにはエッジがある、と考えられる。これをfounder graph という。
founder graph のエッジは、「アレルのgenotype」で、エッジは「ヒトのdiplotype genotype」である。
エッジで結ばれないノードは、singleton と呼ばれ、ぼっちである。


 
ノード(アレル)のgenotype が決まって欲しい。これは、エッジがヒトに対応していることを考えると、エッジで結ばれているノードが取りうるgenotype の組み合わせから解く。例えば、F2 の(21)は(a,b) であり、1番のアレルと3番のアレルがどちらも{a,b}のどちらかを取りうるとき、1番アレルと3番アレルは一意には決まらない。一方で、6番のアレルはF1 の(13)とF2 の(24) に受け継がれるが、(13)が(a,b)、(24)が(b,d) であることを考慮すると、積集合をとって6番のアレルは{b} に一意に決まる。

各アレルの取りうるgenotype を決めていくが、とりあえず適当にノードを選び、ありえそうなgenotype パターンで埋めてみて、埋まるようならば記録して、全体がうまく決まらないようならばその埋め方は破棄する。
 
founder graph のパターンが全部でm個、C_m とすると、アレルの割り当てパターンがA_mとなる。A_m は、singleton でなければ0か1か2個である。
graph component が例えば{1,3,5} のとき、アレルの割り当て確率はPr(a)^2Pr(b)+Pr(a)Pr(b)^2 となる。
A_m のなかのどれかA_i空集合のときは、Pr(m|v)=0 である。また、singleton は確率1になるので、掛けても関係ないから無視してよい。
Pr(a_{hi})=\prod_{{j:j\in C_i}}Pr(a_j)a_{hi}A_i の要素で、C_i のグラフのノードにアレルが割り当てられた情報をもつベクトル。
Pr(C_i)=\sum_{h:a_{hi}\in A_i}}Pr(a_{hi})
Pr(m|v)=\prod_{i=1}^m Pr(C_i)


 
v\{0,1\} のベクトルで、いろんな遺伝子座で長い行列を作ることができる。隣同士を比べて変化があればそこは組み換えがあったと考えてよく、隣り合うものを比較するときにマルコフ過程を使う、というのがキモらしい。

医学・生命科学研究に使える遺伝統計関連のデータベース

遺伝統計夏の学校というものに来ている。
データベースが増えすぎていてすべてはもちろんわからないので、知った時に知識を増やしておこう。
スライドより一覧。
 
ゲノム・遺伝子情報のWebツール
UCSC Genome Browser https://genome.ucsc.edu/cgi-bin/hgGateway
ゲノム配列の標準的な閲覧サイト。遺伝子周辺のヒトゲノム領域において、塩基配列・遺伝子情報・エピゲノム情報・SNP、等の情報を閲覧することができます。
 
NCBI Gene http://www.ncbi.nlm.nih.gov/gene/
遺伝子情報を集約した標準的なデータベースです。
 
HGNC (HUGO Gene Nomenclature Committee) http://www.genenames.org/
遺伝子の名称をまとめた公式サイトです。
 
EMBL-EBI http://www.ebi.ac.uk/
遺伝子情報を集約した標準的なデータベースです
 
Ensembl http://asia.ensembl.org/index.html
遺伝子情報を集約した標準的なデータベースです
 
miRBase http://www.mirbase.org/
マイクロRNA情報を集約した標準的なデータベースです。
 
IMGT/HLA http://www.ncbi.nlm.nih.gov/gene/
HLA遺伝子配列情報(=白血球の血液型)を集約したデータベースです。
 
遺伝子変異・SNP情報のWebツール
dbSNP http://www.ncbi.nlm.nih.gov/SNP/
SNP情報を集約した標準的なデータベースです
 
ClinVar http://www.ncbi.nlm.nih.gov/clinvar/
疾患リスクに重点を置いてSNP情報を集約したデータベースです。
 
1000 Genomes Project http://www.1000genomes.org/
多数の人類集団2500人の全ゲノムシークエンス結果を公開しています。
 
NHLBI Exome Sequencing Project (ESP) http://evs.gs.washington.edu/EVS/
複数集団6千人の全エクソームシークエンス結果を公開しています。
 
ExAC Browser http://exac.broadinstitute.org/
複数集団6万人の全エクソームシークエンス結果を公開しています。
 
HaploReg http://www.broadinstitute.org/mammals/haploreg/haploreg.php
SNP同士の連鎖不平衡関係(集団内分布の非独立性)やエピゲノム情報を提供するデータベースです。
 
SNP@Evolutinon http://124.16.129.22/db/index.php
各遺伝子変異が集団の中で受ける選択圧(生存の有利/不利)の指標がまとめられています。
 
疾患感受性遺伝子情報・解析結果のWebツール
GWAS catalog https://www.ebi.ac.uk/gwas/
GWAS結果(疾患名・遺伝子名・SNP名・論文名)のアーカイブサイトです。
 
OMIM (Online Mendelian Inheritance in Man) http://www.omim.org/
希少疾患を中心に、感受性遺伝子情報を集約したデータベースです。
 
GIANT consortium http://portals.broadinstitute.org/collaboration/giant/index.php/GIANT_consortium_data_files
身長/肥満GWASの全SNPの結果がダウンロードできるサイトです。
 
MAGIC http://www.magicinvestigators.org/downloads/
インスリン代謝GWASの全SNPの結果がダウンロードできるサイトです。
 
AMD Gene Consortium http://csg.sph.umich.edu//abecasis/public/amdgene2012/
AMD GWASの全SNPの結果がダウンロードできるサイトです。
 
Global Lipids Genetics Consortium http://csg.sph.umich.edu//abecasis/public/lipids2013/
脂質GWASの全SNPの結果がダウンロードできるサイトです。
 
Global Urate Genetics Consortium http://metabolomics.helmholtz-muenchen.de/gugc/
尿酸値/痛風GWASの全SNPの結果がダウンロードできるサイトです。
 
CKDGEN http://www.nhlbi.nih.gov/research/intramural/researchers/pi/fox-caroline/datasets
腎機能GWASの全SNPの結果がダウンロードできるサイトです。
 
The International Genomics of Alzheimer's Project http://web.pasteur-lille.fr/en/recherche/u744/igap/igap_download.php
アルツハイマー病GWASの全SNPの結果がダウンロードできるサイトです。
 
IBD Genetics http://www.ibdgenetics.org/downloads.html
炎症性腸疾患GWASの全SNPの結果がダウンロードできるサイトです。
 
遺伝統計学分野HP http://www.sg.med.osaka-u.ac.jp/tools.html
関節リウマチGWASの全SNPの結果がダウンロードできるサイトです。
 
ReproGen Consortium http://www.reprogen.org/data_download.html
初潮開始年齢GWASの全SNPの結果がダウンロードできるサイトです。
 
Locus Zoom http://locuszoom.sph.umich.edu/locuszoom/
GWAS解析結果の、領域内SNP P値の図を書くことができるサイトです。
 
COSMIC (Catalogue of Somatic Mutations in Cancer) http://cancer.sanger.ac.uk/cosmic
がん体細胞変異情報が蓄積されたカタログデータベースです。
 
エピゲノム情報のWebツール
GEO database http://www.ncbi.nlm.nih.gov/geo/
遺伝子発現データベースサイトです。
 
GTEx Portal http://www.gtexportal.org/home/
900名の献体から得られた体内組織の遺伝子発現データが公開されたサイトです。
 
PBMC eQTL browser http://genenetwork.nl/bloodeqtlbrowser/
5000名の末梢血由来遺伝子発現eQTL解析結果の公開サイトです。
 
Human Genetic Variation Database http://www.genome.med.kyoto-u.ac.jp/SnpDB/index.html
日本人集団エクソーム解析で得られた、ゲノム変異のデータベースです。
 
ENCODE (Encyclopedia of DNA Elements) https://www.encodeproject.org/
組織特異的エピゲノム情報を網羅的するENCODEプロジェクトのサイトです。
 
geuvadis http://www.geuvadis.org/web/geuvadis
eQTL 解析の遺伝子発現量データ
 
創薬情報のWebツール
DRUGBANK http://www.drugbank.ca/
治療薬とその標的遺伝子に関するデータベースサイトです。
 
TTD (Therapeutic Targets Database) http://bidd.nus.edu.sg/group/cjttd/TTD_HOME.asp
治療薬とその標的遺伝子に関するデータベースサイトです。
 
SuperTarget http://insilico.charite.de/supertarget/index.php
治療薬とその標的遺伝子に関するデータベースサイトです。特に標的遺伝子に注力されています。
 
STITCH http://stitch.embl.de/cgi/show_input_page.pl
化合物とタンパク質が構成するネットワーク情報のサイトです。
 
STRING http://string-db.org/
タンパク質間相互作用ネットワーク情報のサイトです。

HWE とLD

アレルA とアレルa がある。
アレルA の存在確率がpのとき、アレルa の存在確率は1-pである。
1世代交配して得られる遺伝子型は(AA, Aa, aa)=(p^2,2p(1-p),(1-p)^2)である。
これは、アレルA とアレルA を持つ者同士は強制的に子孫残してね、というような神の見えざる手が働かない、つまり、完全にランダムなときにこの比率になる。
この場合にHWE という。
実際には、完全にランダム、とはならず、とある係数F(近交係数と呼ばれる)により
\begin{pmatrix}AA\\Aa\\ aa \end{pmatrix}=\begin{pmatrix}p^2+p(1-p)F\\2p(1-p)(1-F)\\(1-p)^2+p(1-p)F\end{pmatrix}
となる。
AA とaa からFが計算できるので、ゴリ押しすると

N1 <- c(36, 48, 16) # p = 0.6, F = 0
N2 <- c(42, 36, 22) # p = 0.6, F = 0.25
HWE_F <- function(vec){
  p <- ((vec[1]-vec[3])/sum(vec)+1)/2
  F <- 1-vec[2]/sum(vec) /2/p/(1-p)
  return(list(p=p, F=F, 
              HWE=c(p^2, 2*p*(1-p), (1-p)^2),
              HWD=c(p^2+p*(1-p)*F, 2*p*(1-p)*(1-F), (1-p)^2+p*(1-p)*F)))
}
HWE_F(N1) # F = 0
$p
[1] 0.6

$F
[1] 0

$HWE
[1] 0.36 0.48 0.16

$HWD
[1] 0.36 0.48 0.16
HWE_F(N2) # F > 0
$p
[1] 0.6

$F
[1] 0.25

$HWE
[1] 0.36 0.48 0.16

$HWD
[1] 0.42 0.36 0.22

 
アレルA/a, B/b の組を考える。確率はそれぞれ、p_a, 1-p_a, p_b, 1-p_bである。
これがお互いになんの関係もなく、交配したとしたら、次世代の遺伝子型の確率は次のようになる。
\begin{matrix} & A:p_a & a:1-p_a & \\ B:p_b & p_ap_b & (1-p_a)p_b & p_b \\ b:1-p_b & p_a(1-p_b) & (1-p_a)(1-p_b)&1-p_b \\ & p_a & 1-p_a & 1 \end{matrix}
いま、A/a, B/b が独立ではなく、連鎖不平衡という現象によって偏って次世代に交配すると
\begin{pmatrix}AB\\Ab\\aB\\ab\end{pmatrix}=\begin{pmatrix}p_ap_b+\delta\\p_a(1-p_b)-\delta\\(1-p_a)p_b-\delta\\(1-p_a)(1-p_b)+\delta\end{pmatrix}
ただし、\delta=r\sqrt{p_a(1-p_a)p_b(1-p_b)}
AB とab から\deltaを消去すると
\begin{pmatrix}p_a+p_b\\p_a-p_b\end{pmatrix}=\begin{pmatrix}1+AB-ab\\Ab-aB\end{pmatrix}
\begin{pmatrix}1&1\\1&-1\end{pmatrix}\begin{pmatrix}p_a\\p_b\end{pmatrix}=\begin{pmatrix}1+AB-ab\\Ab-aB\end{pmatrix}
となる二次方程式をsolve で解けばよい。

M1 <- matrix(c(42, 18, 28, 12), 2) # p1 = 0.6, p2 = 0.7, r = 0
M2 <- matrix(c(48, 12, 22, 18), 2) # r ~ 0.25
LD <- function(mat){
  a <- matrix(c(1, 1, 1, -1), 2)
  b <- c(1+(mat[1,1]-mat[2,2])/sum(mat), (mat[2,1]-mat[1,2])/sum(mat))
  p12 <- solve(a, b)
  delta <- mat[1,1]/sum(mat) - prod(p12)
  LE <- matrix(c(prod(p12), p12[1]*(1-p12[2]), (1-p12[1])*p12[2], prod(1-p12)), 2)
  return(list(p = p12, r = delta/sqrt(prod(c(p12, 1-p12))),
              LE = LE, LD = LE + matrix(c(1, -1, -1, 1), 2)*delta))
}
LD(M1) # No disequilibrium
$p
[1] 0.6 0.7

$r
[1] -2.472663e-16

$LE
     [,1] [,2]
[1,] 0.42 0.28
[2,] 0.18 0.12

$LD
     [,1] [,2]
[1,] 0.42 0.28
[2,] 0.18 0.12
LD(M2) # with disequilibrium
$p
[1] 0.6 0.7

$r
[1] 0.2672612

$LE
     [,1] [,2]
[1,] 0.42 0.28
[2,] 0.18 0.12

$LD
     [,1] [,2]
[1,] 0.48 0.22
[2,] 0.12 0.18

塩基のIUPAC表記

塩基はACTG の4文字からなるが、C もしくはG のように代替パターンがあるときにS などの表記がIUPAC で決まっている。
seqinr パッケージの関数でできて、 C/G がS であることを確認するにはbma, S がC/G であることを確認するにはamb を使う。

amb(c("s"))
[1] "c" "g"
bma(c("c", "g"))
[1] "s"