edgeR — リードカウントから発現変動遺伝子を検出
https://bioconductor.org/packages/release/bioc/html/edgeR.html
Robinson MD, McCarthy DJ, Smyth GK (2010) “edgeR: a Bioconductor package for differential expression analysis of digital gene expression data.” Bioinformatics 26 (1):139–140 https://www.ncbi.nlm.nih.gov/pubmed/19910308
Bioconductor パッケージとしてインストール
BiocManager::install("edgeR")
ユーザーガイドPDFを開く
edgeRUsersGuide()
とても良くできたドキュメントなので必読
使い方
-
HTSeq
などで遺伝子ごとのリードカウントを用意する -
Rで読み込む
library(edgeR) targets = data.frame(group=c("control", "case"), files=c("control.txt", "case.txt")) dge = readDGE(targets, header = FALSE)
-
低カウント過ぎる遺伝子を除去
ok_c = (dge$counts > 5) |> rowSums() |> as.logical() ok_cpm = (cpm(dge) > 1) |> rowSums() |> as.logical() dge = dge[ok_c & ok_cpm, , keep.lib.sizes = FALSE]
-
正規化係数を計算
dge = calcNormFactors(dge) dge$samples
-
モデル
design = model.matrix(~ 0 + group, data = targets)
-
common dispersion, trended dispersion, tagwise dispersionを推定
dge = estimateDisp(dge, design)
ただしこれにはbiological replicatesが必要。 1グループ1サンプルずつしか無い場合は4つの選択肢がある。
-
検定を諦めてdescriptive discussion (推奨)
-
経験的な値を適当に入れとく
bcv = 0.4 # for human bcv = 0.1 # for genetically identical model organisms bcv = 0.01 # for technical replicates dge$common.dispersion = bcv ^ 2
-
説明変数を減らしたモデルでdispersionを推定し、フルモデルで使う
reduced = estimateGLMCommonDisp(dge, reduced.design, method="deviance", robust=TRUE, subset=NULL) dge$common.dispersion = reduced$common.dispersion
合計カウントが多くてDEGが比較的少ないときに有効。 当然、1変数2群比較では使えない。
-
群間で差がないと考えられるhousekeeping genesから推定。 100個以上の遺伝子を使うのが望ましい。 例えばヒトなら
system("wget https://www.tau.ac.il/~elieis/HKG/HK_genes.txt") hk_genes = read_tsv("HK_genes.txt", col_names=c("gene_symbol", "refseq")) tmp = dge tmp$samples$group = 1 housekeeping = rownames(tmp$counts) %in% hk_genes$gene_symbol hk = estimateCommonDisp(tmp[housekeeping,]) dge$common.dispersion = hk$common.dispersion
-
-
1変数2群ならシンプルに検定
et = exactTest(dge) topTags(et, 20, adjust.method="BH", sort.by="PValue")
多群ならGLMで尤度比検定
fit = glmFit(dge, design) lrt = glmLRT(fit, coef=2:3) lrt_1vs2 = glmLRT(fit, coef=2) lrt_1vs3 = glmLRT(fit, coef=3) lrt_2vs3 = glmLRT(fit, contrast=c(0, -1, 1))
検定結果からDEGを抜き出す
min_lfc = 1 de = decideTestsDGE(et, adjust.method="BH", p.value=0.01, lfc=min_lfc) de_tags = rownames(dge)[as.logical(de)]
P値とlogFCの両方で切ったほうがいいらしい。
topTags()
やdecideTestsDGE()
で多重検定の補正をするということは、et
やlrt
のPValue
は補正前。 -
プロット
logFC ~ mean(logCPM)
してみるplotSmear(et, de.tags=de_tags) abline(h=min_lfc * c(-1, 1), col="blue")
-
Gene Ontology解析
go = goana(lrt, species="Hs") topGO(go)
NCBI RefSeqアノテーションを使うのでIDはEntrez系で
Appendix
レプリケート i における遺伝子 g の観察リード数を $y _{gi}$、 知りたい真の発現fractionを $\pi _{gi}$ とする。
- dispersion $\phi _g$
- 普通は $D = \sigma^2 / \mu$ と定義されるけど、 ここでは $\text{CV}^2$
- BCV $\sqrt{\phi _g}$
- biological coefficient of variation. こっちは普通と同じように $\text{CV} = \sigma / \mu$ 。 sequencing depthがどんなに大きくても残るばらつき。
- DGE
- digital gene expression
- CPM
- counts per million
- logFC
- log2-fold-change