SNPデータの読み込み、GWA解析にgastonを用いる。Rのパッケージインストーラで簡単にダウンロード・インストールできる。また、多変量正規分布にしたがう乱数を発生させるためにmvtnormを用いる。こちらも読み込んでおく。
require(gaston) # for reading a vcf file and performing GWAS
require(mvtnorm) # 多変量正規分布に従う乱数の発生
まず、vcf 形式のマーカー遺伝子型データ(McCouch ら 2016) を読み込む。vcf 形式のデータの読み込みには、gastonパッケージに含まれる関数read.vcfを用いる。
# vcfファイルの読み込み
bm <- read.vcf("data/HDRA-G6-4-RDP1-RDP2-NIAS.AGCT_MAF005MIS001NR_imputed.vcf.gz")
## ped stats and snps stats have been set.
## 'p' has been set.
## 'mu' and 'sigma' have been set.
bm # データのsummaryが表示される
## A bed.matrix with 1568 individuals and 38769 markers.
## snps stats are set
## ped stats are set
まず、疑似乱数の種をセットしておく。これにより、以下の解析で同じ結果が得られる。
set.seed(20210622)
データの準備。計算負荷を小さくするためにデータ数を減らす。ここでは、客観的な方法(k-medoids法)を用いて予め選んでおいた代表的な500系統を解析に用いる。なお、k-medioids法での代表選びのためのRコードはhttps://rpubs.com/hiroiwata/627490にある。
id.med <- read.csv("data/id_med.csv", row.names = 1)$id.med # 代表500系統のid
bm.sim <- bm[id.med, ] # idのある系統を抽出
bm.sim <- select.snps(bm.sim, maf > 0.05) # MAFが5%以下のものを除いておく
bm.sim
## A bed.matrix with 500 individuals and 36502 markers.
## snps stats are set
## ped stats are set
500系統の36,502マーカーのデータとなっている。
繰り返し利用することになる血縁行列とその固有値分解を予め行っておく。
standardize(bm.sim) <- "mu_sigma"
grm <- GRM(bm.sim)
eigen.grm <- eigen(grm)
全SNPから、QTN (quantitative trait nucleotides)を無作為に選ぶ。
n <- ncol(bm.sim) # 全SNP数
n.qtn <- 6 # QTNの数
qtn.id <- sample(n, n.qtn) # n.qtn個のSNPをQTNとして無作為に選ぶ
X.qtn <- as.matrix(bm.sim[, qtn.id]) # QTNの遺伝子型スコアを抜き出す
次に、シミュレーションにおけるQTNの効果を決め、それらQTNによる遺伝変異を全系統について計算する。
w.qtn <- rep(1.0, n.qtn) # 主働遺伝子の効果を、ここでは全て1.0とする
g.qtn <- as.vector(X.qtn %*% w.qtn) # QTNによる変異を全系統について計算
var(g.qtn) # QTN効果による遺伝分散
## [1] 6.607365
効果の小さな遺伝子(ポリジーン、微働遺伝子)による効果を擬似的に生成する。生成には、多変量正規分布からの乱数を用いる。QTNによる遺伝変異の大きさに応じて発生させるように、先にQTNによる遺伝変異の分散(遺伝分散)を計算し、その分散に応じてポリジーンによる効果の大きさを調節する。
# QTNの遺伝分散の何割かをポリジーンによる遺伝分散とする
g.var.ratio <- 0.5 # QTNによる遺伝分散の50%をポリジーンによる遺伝分散にする
# 多変量正規乱数としてポリジーン効果を生成
g.poly <- as.vector(rmvnorm(1, sigma = grm * var(g.qtn) * g.var.ratio))
var(g.poly) # ポリジーン効果による分散
## [1] 3.010467
QTNの効果と微働遺伝子の効果を足し合わせて全系統の遺伝変異(遺伝子型値)を計算する。
g <- g.qtn + g.poly # 遺伝子型値 = QTNの効果 + ポリジーン効果
var(g) # 遺伝分散
## [1] 12.18517
次に、指定した遺伝率に従って環境変異を発生させる。
he <- 0.5 # 遺伝率。ここでは、表現型分散の50%が遺伝分散とする。
var.e <- (1 - he) / he * var(g) # 環境分散を計算する
e <- rnorm(length(g), sd = sqrt(var.e)) # var.eを分散にもつ環境変異を生成
var(e) # 環境分散
## [1] 12.1407
最後に、遺伝変異(遺伝子型値)に環境変異を加え、表現型変異(表現型値)を計算する。
y <- g + e # 遺伝変異に環境変異を加えて表現型変異を計算する
var(y) # 表現型分散
## [1] 24.70915
擬似的に生成した表現型値\(y\)を用いてGWASを行ってみる。
# GWASの実行
gwa.sim <- association.test(bm.sim, Y = y,
method = "lmm", response = "quantitative",
test = "wald", eigenK = eigen.grm, p = 4)
マンハッタンプロットを描く。
fdr.thresh <- 0.05 # 偽発見率のしきい値
fdr <- p.adjust(gwa.sim$p, method = "BH")
col <- rep("black", nrow(gwa.sim))
col[gwa.sim$chr %% 2 == 1] <- "gray50"
col[fdr < fdr.thresh] <- "green"
res <- manhattan(gwa.sim, pch = 20, col = col)
QTNとして検出されたSNPを示す。
res[fdr < fdr.thresh,]
## chr pos id A1 A2 freqA2 h2 beta
## 4534 1 40886543 SNP-1.40885499. G A 0.094 0.3965221 1.760882
## 4535 1 40888164 SNP-1.40887120. G A 0.096 0.3966243 1.677028
## 4536 1 40919729 SNP-1.40918685. G C 0.100 0.3961781 1.837236
## 4544 1 40971632 SNP-1.40970588. C T 0.100 0.3991273 1.883018
## 15056 4 31085326 SNP-4.30900214. C T 0.416 0.3957396 1.175803
## 15063 4 31121686 SNP-4.30936574. T A 0.382 0.3986050 1.300756
## 15115 4 31399386 SNP-4.31214283. G A 0.417 0.3534822 1.152306
## 15117 4 31401844 SNP-4.31216741. C T 0.420 0.3478513 1.198118
## 15118 4 31404256 SNP-4.31219153. A G 0.417 0.3503540 1.209181
## 27222 9 4215265 SNP-9.4214264. A T 0.897 0.4535143 -2.405386
## 27223 9 4218943 SNP-9.4217942. A G 0.894 0.4531454 -2.472885
## 33948 11 27998654 SNP-11.27527039. G A 0.085 0.4269134 1.558582
## 33953 11 28004683 SNP-11.27533068ct. C T 0.097 0.4128545 1.611712
## 33954 11 28005367 SNP-11.27533752. T A 0.088 0.4204711 1.686909
## 33956 11 28006840 SNP-11.27535225. C T 0.093 0.4128481 1.683128
## 33957 11 28007825 SNP-11.27536210. T C 0.092 0.4165065 1.663831
## 33958 11 28008519 SNP-11.27536904. A C 0.090 0.4190640 1.690244
## 33959 11 28008663 SNP-11.27537048. G A 0.094 0.4321907 1.574322
## 33962 11 28010508 SNP-11.27538893. C T 0.091 0.4192054 1.689171
## 33964 11 28011447 SNP-11.27539832. C A 0.053 0.4287450 2.018508
## 33965 11 28011849 SNP-11.27540234. G A 0.094 0.4186767 1.698562
## 33967 11 28012393 SNP-11.27540778. T C 0.093 0.4137468 1.639406
## 35443 12 15864073 SNP-12.15861368. A G 0.130 0.4010476 2.024688
## sd p coord
## 4534 0.3909873 6.678630e-06 0.1096810
## 4535 0.3878442 1.532436e-05 0.1096853
## 4536 0.3909915 2.615469e-06 0.1097700
## 4544 0.4162502 6.074939e-06 0.1099093
## 15056 0.2696611 1.298856e-05 0.3934265
## 15063 0.2559100 3.717847e-07 0.3935241
## 15115 0.2393093 1.471030e-06 0.3942690
## 15117 0.2380599 4.832643e-07 0.3942756
## 15118 0.2372026 3.438570e-07 0.3942821
## 27222 0.5747216 2.847809e-05 0.7359077
## 27223 0.5645902 1.186990e-05 0.7359176
## 33948 0.3587717 1.397745e-05 0.9234598
## 33953 0.3399142 2.121158e-06 0.9234759
## 33954 0.3515551 1.599215e-06 0.9234778
## 33956 0.3430037 9.246687e-07 0.9234817
## 33957 0.3460448 1.523432e-06 0.9234844
## 33958 0.3484469 1.229678e-06 0.9234862
## 33959 0.3515774 7.538696e-06 0.9234866
## 33962 0.3472309 1.146353e-06 0.9234916
## 33964 0.4666217 1.519856e-05 0.9234941
## 33965 0.3440694 7.946172e-07 0.9234952
## 33967 0.3431801 1.778414e-06 0.9234966
## 35443 0.3292835 7.808718e-10 0.9687134
次に、QTNとしたSNPの検定の結果、および、マンハッタンプロットのx軸上での位置を確認する。
res[qtn.id,]
## chr pos id A1 A2 freqA2 h2 beta sd
## 15115 4 31399386 SNP-4.31214283. G A 0.417 0.3534822 1.1523060 0.2393093
## 33967 11 28012393 SNP-11.27540778. T C 0.093 0.4137468 1.6394056 0.3431801
## 28516 9 18959418 SNP-9.18958417. C A 0.677 0.4407520 -0.2602716 0.4279641
## 35443 12 15864073 SNP-12.15861368. A G 0.130 0.4010476 2.0246880 0.3292835
## 4544 1 40971632 SNP-1.40970588. C T 0.100 0.3991273 1.8830178 0.4162502
## 15568 5 434397 SNP-5.434396. G A 0.407 0.4166602 0.9940285 0.2729061
## p coord
## 15115 1.471030e-06 0.3942690
## 33967 1.778414e-06 0.9234966
## 28516 5.430799e-01 0.7754599
## 35443 7.808718e-10 0.9687134
## 4544 6.074939e-06 0.1099093
## 15568 2.701259e-04 0.4063281
QTNとしたSNPの位置をピンク色の垂線で表す。
res <- manhattan(gwa.sim, pch = 20, col = col)
abline(v = res$coord[qtn.id], col = "pink") # 垂線を引く
偽発見率、偽陽性率を計算する。なお、QTNの近くにあるSNPで検出されたものは真の陽性と判断することとする。
is.close2QTN <- rep(F, nrow(bm.sim@snps)) # QTNおよびその周辺であれば真になる
is.detected <- rep(F, n.qtn) # そのQTNが検出されるかどうか
range <- 1e6 # QTNから1Mb以内は、正しく検出したものとする
for(i in 1:n.qtn) {
qtn <- bm.sim@snps[qtn.id[i],] # 1つのQTNずつ調べる
cond.chr <- bm.sim@snps$chr == qtn$chr # 染色体番号が一致するか?
cond.pos1 <- bm.sim@snps$pos > qtn$pos - range # QTNの位置より-range〜
cond.pos2 <- bm.sim@snps$pos < qtn$pos + range # +rangeに入っているか?
is.close2QTN <- is.close2QTN | (cond.chr & cond.pos1 & cond.pos2) # QTNおよびその周辺
is.detected[i] <- sum(fdr < fdr.thresh & (cond.chr & cond.pos1 & cond.pos2)) > 0
}
n.positive <- sum(fdr < fdr.thresh) # 陽性であったSNP数
n.positive
## [1] 23
n.negative <- sum(!(is.close2QTN)) # 陰性となるべき(QTLの近くにない)SNP数
n.negative
## [1] 35217
n.false.positive <- sum(!(is.close2QTN) & fdr < fdr.thresh)
# 偽陽性のSNP数(本当は陰性なのに陽性になったSNP数)
n.false.positive
## [1] 2
fdr.obs <- n.false.positive / n.positive # 偽陽性のSNP数 / 陽性であったSNP数
fdr.obs # 偽発見率
## [1] 0.08695652
fpr.obs <- n.false.positive / n.negative # 偽陽性のSNP数 / 陰性となるべきSNP数
fpr.obs # 偽陽性率
## [1] 5.679075e-05
n.undetected <- sum(!(is.detected))
# 検出されなかったQTN数(近くにSNPが検出されなかったQTN)
n.undetected
## [1] 2
fnr.obs <- sum(!(is.detected)) / n.qtn # 検出されなかったQTN数 / 全QTN数
fnr.obs # 偽陰性率
## [1] 0.3333333