LoginSignup
1
1

More than 1 year has passed since last update.

リードカウントが0のFold Changeはなぜ計算ができるのか edgeR, RNA-seq解析 [備忘録]

Last updated at Posted at 2021-05-21

RNA-seq解析の発現変動遺伝子を検出する方法として、RパッケージのedgeRやDEseqが有名です。その際に、条件間でのFold Change、つまり発現差を計算するのですが、リードカウントが0の場合は0で割ることはできないのでFold Changeを算出することができません。
今回はedgeR内でどのような処理を行い、Fold Changeを算出可能なのか、備忘録としてまとめたいと思います。
結論だけ知りたい方は一番下のまとめをご覧ください。

####シミュレーションデータについて
シミュレーションデータはRのTCCパッケージで作成したものを用いました。
データの作成方法については以下の記事から

####edgeRでの遺伝子発現変動比較解析の流れ
まずは、edgeRで発現変動比較解析の流れを説明します。
edgeRについては、以下の文献を参照してください。
DOI: 10.1093/bioinformatics/btp616

今回はbiological replicateを1として2群間比較を行います。
以下にログを示します。

> #パッケージの読み込み
> library(edgeR)

> #パッケージバージョンの確認
> packageVersion("edgeR")
[1] ‘3.32.1’

> #カウントデータの読み込み
> count <- read.csv("TCC_simulation_data.csv", header = T, row.names = 1)

> #カウントデータの抽出
> count <- count[, c(3, 6)]
> head(count)
       G1_rep3 G2_rep3
gene_1      32      10
gene_2      28       0
gene_3     158      74
gene_4      68      10
gene_5     235     115
gene_6     116      47

> #行列型への変換
> count <- as.matrix(count)
> dim(count)
[1] 10000     2

> #実験群の識別ラベルを作成し、group変数に代入
> group <- factor(c("condition1", "condition2"))

> #カウントデータと実験群の識別ラベルを一つの変数に代入
> d <- DGEList(counts = count, group = group)

> #TMM正規化
> d <- calcNormFactors(d)
> d
An object of class "DGEList"
$counts
       G1_rep3 G2_rep3
gene_1      32      10
gene_2      28       0
gene_3     158      74
gene_4      68      10
gene_5     235     115
9995 more rows ...

$samples
             group lib.size norm.factors
G1_rep3 condition1  1507360     0.851503
G2_rep3 condition2   982924     1.174394

> #edgeRによる2群間比較
> d <- estimateGLMCommonDisp(d, method = "deviance", robust = T, subset = NULL)

> #exact test
> result <- exactTest(d)

> result
An object of class "DGEExact"
$table
            logFC   logCPM     PValue
gene_1 -1.5139769 4.207542 0.39146424
gene_2 -7.7396297 3.657546 0.01129089
gene_3 -0.9401836 6.573969 0.53604662
gene_4 -2.5983076 5.023355 0.12333235
gene_5 -0.8773113 7.160117 0.55946082
9995 more rows ...

$comparison
[1] "condition1" "condition2"

$genes
NULL

長くなりましたが、解析はこのような流れになります。
ここで注目していただきたいのは、G2_rep3のgene_2です。リードカウントは0になっていますが、excat testの結果の後の「result」では、logFC (Fold ChangeをLog表記したものです)が-7.7396・・・となっています。
単純に考えると不思議な結果です。
G1_rep3のgene_2のリードカウントは28、G2_rep3のgene_2は0ですから、0/28となり、計算できないはずです。
なぜ、このような現象が生じるのでしょうか。

####TMM正規化で処理がされている?
TMM正規化とは、非発現変動遺伝子はMAプロット上でM値が0となると仮定し、そのようになるように係数を掛ける手法です(詳しくは以下のサイトを参照)。

つまり、TMM正規化ではリードカウントに係数を掛ける処理しかしないので、カウントが0であれば0のままです。
TMM正規化をするだけではFold Changeは計算できないままのようです。

####edgeRによる2群間比較の際に処理されている?
edgeRで使用した関数は主に以下の二つです。

estimateGLMCommonDisp(d, method = "deviance", robust = T, subset = NULL)
exactTest(d)

このどちらかで何らかの処理がされていると考えられます。
まずはestimateGLMCommonDisp関数から調べました。
以下をRstudioのコンソールに記入します。

?estimateGLMCommonDisp

そうすると、help画面が起動し、estimateGLMCommonDisp関数のArgumentsなどを見ることができます。しかし、helpを見ても特に関連しそうな項目は見つかりません。

次に、exactTest関数について調べました。

?exactTest

すると、関連しそうな項目がありました(以下はRのhelp画面からの引用です)。

Usage
exactTest(object, pair=1:2, dispersion="auto", rejection.region="doubletail",
          big.count=900, prior.count=0.125)

Arguments
prior.count	
average prior count used to shrink log-fold-changes. Larger values produce more shrinkage.

Argumentsのprior.countが原因だったようです。
これにより、prior.countで指定した数字をTMM正規化後の数値に足すことで、リードカウントが0であるものを無くし、Fold Changeが正常に計算できるようになっています。
デフォルトは0.125のようです。
試しにprior.countを0に指定してみます。

> #exact test
> result <- exactTest(d, prior.count=0)
> result
An object of class "DGEExact"
$table
            logFC   logCPM     PValue
gene_1 -1.5250327 4.207542 0.39146424
gene_2       -Inf 3.657546 0.01129089
gene_3 -0.9412882 6.573969 0.53604662
gene_4 -2.6124956 5.023355 0.12333235
gene_5 -0.8779877 7.160117 0.55946082
9995 more rows ...

$comparison
[1] "condition1" "condition2"

$genes
NULL

gene_2のlogFCが-Infとなっています。前述したようにG1_rep3のgene_2のリードカウントは28、G2_rep3のgene_2は0ですから、0/28となり、-Infとなるはずなので、予想された結果が得られたということになります。

デフォルト値について、usageに書いてある情報しか見つからなかったので、一応デフォルトが0.125なのかどうかも調べてみましょう。

> #exact test
> result <- exactTest(d, prior.count=0.125)
> result
An object of class "DGEExact"
$table
            logFC   logCPM     PValue
gene_1 -1.5139769 4.207542 0.39146424
gene_2 -7.7396297 3.657546 0.01129089
gene_3 -0.9401836 6.573969 0.53604662
gene_4 -2.5983076 5.023355 0.12333235
gene_5 -0.8773113 7.160117 0.55946082
9995 more rows ...

$comparison
[1] "condition1" "condition2"

$genes
NULL

少しわかりにくいので以下に、デフォルト設定で行ったもの、0.125で指定したものを上下に並べてみました。

デフォルト設定
            logFC   logCPM     PValue
gene_1 -1.5139769 4.207542 0.39146424
gene_2 -7.7396297 3.657546 0.01129089
gene_3 -0.9401836 6.573969 0.53604662
gene_4 -2.5983076 5.023355 0.12333235
gene_5 -0.8773113 7.160117 0.55946082

prior.countを0.125に設定
            logFC   logCPM     PValue
gene_1 -1.5139769 4.207542 0.39146424
gene_2 -7.7396297 3.657546 0.01129089
gene_3 -0.9401836 6.573969 0.53604662
gene_4 -2.5983076 5.023355 0.12333235
gene_5 -0.8773113 7.160117 0.55946082

全遺伝子については大変なので比較しませんが、最初の5遺伝子を比べると、logFCを含めて全ての値がデフォルト設定とprior.countを0.125にしたものが同じ値となっており、デフォルトが0.125だったのは本当のようです。

####まとめ
長くなりましたが、備忘録として、RパッケージのedgeRでリードカウントが0の場合になぜFold Changeが計算できるのかを調べてみました。
結論としては、edgeRのexactTest関数内でprior.countというArgumantにより、TMM正規化後の数値に特定の数値(デフォルトは0.125)を足すことでリードカウントが0にならないようにし、Fold Changeの算出(つまりリードカウント同士の割り算)ができるようになっていた、ということでした。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1