本書と直接関係のない部分もありますが、初心者の方は基本的にはざっとでよいので順番通りにやっていくとよいと思います。
Rに慣れることを目的として、「1.2.1
サンガー法の原理」の冒頭部分で述べた相補鎖や逆相補鎖をRで得るやり方を解説します。まずはBiostringsパッケージをロードして、このパッケージが提供するcomplement
やreverseComplement
関数を使えるようにします。
library(Biostrings)
次に、本文中で示したものと同じ塩基配列をsequenc
という名前のオブジェクトに格納し、その中身を表示させます。背景が灰色になっている部分がコマンド、##から始まっている背景が白くなっている部分が実行結果です。当たり前といえば当たり前ですが、入力と同じ配列が出力されていることがわかります。
sequenc <- "AGTGACGGTCTT"
sequenc
## [1] "AGTGACGGTCTT"
今取り扱っているsequenc
オブジェクトの中身は、見た目上明らかに塩基配列です。しかし、Biostringsパッケージが提供する相補鎖や逆相補鎖を得るための関数を利用するためには、これが塩基配列だと正しく認識させておかねばなりません。そこで次に、sequenc
を入力としてDNAStringSet
という関数を実行し、その結果をfasta
という名前のオブジェクトに格納する作業を行います。先ほどと同じく、背景が灰色になっている部分がコマンド、##から始まっている背景が白くなっている部分が実行結果です。背景が白の実行結果部分において、width
列の12という数値が塩基数、seq
列が実際の塩基配列になっていることがわかります。左下に見えている[1]
はまだ気にしなくてもよいです。最初の行で見えているDNAStringSet object
というのが、(塩基)配列情報をBiostringsパッケージで取り扱うために定義された特有の形式なのだという理解でよいです。
fasta <- DNAStringSet(sequenc)
fasta
## DNAStringSet object of length 1:
## width seq
## [1] 12 AGTGACGGTCTT
いよいよ本番1として、相補鎖を得るためのcomplement
関数を実行します。入力はDNAStringSet
形式のfasta
オブジェクトです。確かに実行結果として見えているものは、本文中のものと同じ”TCACTGCCAGAA”です。
complement(fasta)
## DNAStringSet object of length 1:
## width seq
## [1] 12 TCACTGCCAGAA
本番2として、逆相補鎖を得るためのreverseComplement
関数を実行します。確かに実行結果として見えているものは、本文中のものと同じ”AAGACCGTCACT”です。なお、以下ではreverseComplement(fasta)
としていますが、reverseComplement(x=fasta)
と書いても構いません。
reverseComplement(fasta)
## DNAStringSet object of length 1:
## width seq
## [1] 12 AAGACCGTCACT
次に、存在しないオブジェクトuge
の中身を見ようとして、どういうエラーが出るかを眺めます。このWebページはR
Markdownで自動的に作成しているため若干エラーメッセージの内容が異なっているかもしれませんが、「オブジェクト 'uge' がありません(object 'uge' not found
)」のようなメッセージ表示されていることがわかります。このように、原因が明らかなエラーメッセージを眺めておけば、実際に遭遇する問題に対処しやすいです。
uge
## Error in eval(expr, envir, enclos): オブジェクト 'uge' がありません
以下では、存在しないuge
を入力として、逆相補鎖を返すreverseComplement
関数の実行を試みています。重要なことは、エラーメッセージの中から対処すべき事柄が「オブジェクト 'uge' がありません(object 'uge' not found
)」だけだと読み解くことです。
reverseComplement(uge)
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'reverseComplement' に対するメソッドの選択時): オブジェクト 'uge' がありません
逆相補鎖を返すreverseComplement
関数は、入力としてDNAStringSet object
を受け付けます。そこで次に、ただの文字列であるsequenc
オブジェクトを入力として実行してみます。エラーメッセージだけを見ると、何をどうすればよいのかさっぱりわかりませんが、原因既知状態で眺めると穏やかに原因が特定できると思います。たとえば「..."character"...
」が目につくと思いますが、sequenc <- "AGTGACGGTCTT"
からも明らかなように、sequenc
の中身はcharacterです。
sequenc <- "AGTGACGGTCTT"
reverseComplement(sequenc)
## Error in (function (classes, fdef, mtable) : 関数 'reverseComplement' (シグネチャ '"character"' に対する) に対する継承メソッドを見付けることができません
任意のオブジェクトを入力としてclass
関数を実行すると、そのオブジェクトがどういうものかを調べることができます。class
実行結果も、エラーへの対応(これをデバッグといいます)を行う上で有用な情報となります。
class(sequenc)
## [1] "character"
fasta <- DNAStringSet(sequenc)
class(fasta)
## [1] "DNAStringSet"
## attr(,"package")
## [1] "Biostrings"
次に、存在しないuge
オブジェクトを入力として、再度reverseComplement(uge)
の実行結果を眺めます。よく見ると、自分が指定した覚えのない「引数
‘x’
の評価中にエラーが起きました」のようなエラーメッセージが出ていることがわかります。これは、この関数の場合は、入力であるDNAStringSet object
を受け付ける引数名がxだからです。それがわかっていれば、「reverseComplement(uge)
で入力として与えたuge
の引数名がxだな。なのでこれは引数名を省略しているが、実際にはreverseComplement(x=uge)
だからこのようなメッセージが出ているのだろう」と解釈できるようになります。
reverseComplement(uge)
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'reverseComplement' に対するメソッドの選択時): オブジェクト 'uge' がありません
相補鎖や逆相補鎖を得る程度なら、入力として与える情報は1つだけです。しかし複雑な関数になってくると関数内で複数のオプション(引数)を与えて実行します。複数オプションがある場合は、その関数が想定するデフォルトの順番通りだと引数名を明示しなくても構いません。しかし、入力する側が理解しやすいように引数名を明示することもあります。このあたりのポリシーはヒトそれぞれですので、ユーザ側がこの段階で慣れておくとよいと思います。?reverseComplement
は相補鎖を返すreverseComplement
関数のマニュアルを表示するコマンドです。help(reverseComplement)
でも同じ挙動になります。
?reverseComplement
若干見栄えは異なりますが、上記実行結果とほぼ同じ情報を以下に示します。①や②で見えているx
が、これらの関数で入力として与える情報の引数名です。RStudio上で上記コマンドを実行すると、RStudio画面右下のHelpタブで小さく表示されて見づらい場合は、たとえばBiostringsパッケージのページからリンクが張られているReference
Manualで、調べたい関数名でページ内検索する手もあります。以下の図は「reverseComplement
」でページ内検索してとったスクショです。
RStudio上で塩基配列を手入力し、実行結果がRStudio上に表示されるだけだと実感がわかない方もいらっしゃると思います。ここでは、塩基配列(AGTGACGGTCTT
)ををFASTA形式ファイルとして独立に用意したもの(R1.050.fasta)を入力として用いるやり方を示します。以下は、入力ファイルとしてR1.050.fastaを指定して、Biostringsパッケージをロードして、このパッケージが提供するreadDNAStringSet
関数を用いて読み込んだ結果をfasta
という名前のオブジェクトに格納し、表示させるところまでのスクリプトです。背景が灰色になっている部分がコマンド、##から始まっている背景が白くなっている部分が実行結果です。背景が白の実行結果部分において、width
列の12という数値が塩基数、seq
列が実際の塩基配列、そしてnames
列の情報がFASTA形式ファイルのdescription行部分に相当することがわかります。
in_f <- "R1.050.fasta"
library(Biostrings)
fasta <- readDNAStringSet(in_f, format="fasta")
fasta
## DNAStringSet object of length 1:
## width seq names
## [1] 12 AGTGACGGTCTT hairetsu
次に、逆相補鎖を得たのち、それをout_f
で指定した出力ファイルに保存するまでのスクリプトを示します。reverseComplement(fasta)
実行結果をout
オブジェクトに格納し、それをwriteXStringSet
関数を用いて保存していることが読み解けます。writeXStringSet
関数実行時に、最初の引数としてout
を指定しているのは納得できると思います(逆相補鎖情報を含むout
オブジェクトの中身を保存したいからです)。次に出力ファイル名の引数に相当するfile
という引数で、出力ファイル名情報が格納されているout_f
を与えています。出力形式は、この場合は"fasta"
形式の一択になりますが念のため明示しています。width
という引数では、1行あたり何塩基とするかを指定するオプションになります。この場合は12塩基しかないので特に気にする必要はありませんが、染色体など長い配列になると、width=60
などを指定して1行あたりの塩基数を多めに設定するのを好むヒトもいます。
in_f <- "R1.050.fasta"
out_f <- "R1.050_out.fasta"
library(Biostrings)
fasta <- readDNAStringSet(in_f, format="fasta")
out <- reverseComplement(fasta)
writeXStringSet(out, file=out_f, format="fasta", width=50)
念のため、以下に逆相補鎖情報を含むout
オブジェクトの中身を示しておきます。エラーなく実行できたヒトは、出力ファイル名として指定したR1.050_out.fastaが作業ディレクトリ上に保存されているはずです。
out
## DNAStringSet object of length 1:
## width seq names
## [1] 12 AAGACCGTCACT hairetsu
(1.1)式は、ある塩基のベースコールがエラーとなる確率pを入力として、その塩基のクオリティスコアqを返すものです。本文中でいくつかの入力と出力の関係をいくつか例示していますが、簡単ですのでRStudioでの計算例を示します。以下は、p = 0.01の結果です。確かに出力結果としてq = 20が得られていることがわかります。
p <- 0.01
q <- -10*log(p, base=10)
q
## [1] 20
次は、数値ベクトルを入力として与えるやり方を示します。たとえば、p =
0.0001のときのqは40だと読み解きます。
p <- c(0.1, 0.01, 0.001, 0.0001)
q <- -10*log(p, base=10)
q
## [1] 10 20 30 40
この場合のqは、4つの要素からなる数値ベクトルです。ベクトルの要素数を調べるlength
関数の入力として与えて実行すると、確かに4という結果が返されます。
length(q)
## [1] 4
ベクトルの2番目の要素情報を取り出したい場合はq[2]
、4番目の要素情報を取り出したい場合はq[4]
のように指定します。
q[2]
## [1] 20
q[4]
## [1] 40
このベクトルqの5番目の要素は存在しないことが分かっていますが、もしq[5]
とやると、Not
Availableを意味するNA
という結果が返されます。
q[5]
## [1] NA
1.7.1項の終盤から1.7.2項の最初のほうで述べているk-mer解析に関する基礎的な事柄に加えて、ショートリードデータを用いたゲノムサイズ推定までの内容を参考資料として以下に提供します。特に、ゲノムサイズ推定は、1.8.2項でも述べたものです。元ネタは、2022年5月17日に行った計3時間分の講義資料です。講義で利用されたい方は、pptx版もありますので、必要に応じてご自由に改変してご利用ください。
1.8.4項の最後にある例題1.1をRでやることもできます。この項目の主目的は、ちょっとややこしいですがそれができるのを実感することです。readDNAStringSet
,
strsplit
, nchar
, rep
,
c
などのRの関数や、Rのノリに慣れてもらうことも兼ねています。ここでは、図1.8aの塩基配列をFASTA形式ファイルとして独立に用意したもの(R1.080.fasta)を入力として用いるやり方を示します。以下は、入力ファイルとしてR1.080.fastaを指定して、Biostringsパッケージをロードして、このパッケージが提供するreadDNAStringSet
関数を用いて読み込んだ結果をfasta
という名前のオブジェクトに格納するところまでのスクリプトです。
in_f <- "R1.080.fasta"
library(Biostrings)
fasta <- readDNAStringSet(in_f, format="fasta")
以下では、入力ファイルの中身に相当するfasta
オブジェクトを表示させています。背景が灰色になっている部分がコマンド、##から始まっている背景が白くなっている部分が実行結果です。DNAStringSet
という独特の形式でFASTA形式ファイルの中身が格納されているのだと理解すればよいです。width
列の60という数値が塩基数、seq
列が実際の塩基配列の最初と最後の部分、そしてnames
列の情報がFASTA形式のdescription行部分に相当します。随分冗長な表現方法だと思われるかもしれませんが、たとえば入力が数十個の染色体配列から構成されるヒトゲノム配列ファイルを読み込んだ場合をイメージしていただければ納得しやすいかと思います。
fasta
## DNAStringSet object of length 1:
## width seq names
## [1] 60 TTGACAATTTCCTGATTCGGACG...ATGAATCCCTCAACTCTATTGCA fig1.8a
以下では、仮想制限酵素の認識配列がACなので、それを用いてfasta
オブジェクト内の塩基配列(文字列なのでstring)を分割(split)するstrsplit
関数を実行しています。実行結果をhoge
オブジェクトに格納しています。2行目のstrsplit
関数実行部分の右側に[[1]]
がついていますが、簡単にいうと話をややこしくしないようにするためのおまじないです。なお、strsplit
関数実行部分で「Warning in .normarg_at2(at, x): 'at' names were ignored
」という警告メッセージが表示されていますが、エラーではないので気にする必要はありません。
補足:例題1.1をRでやるのは、あくまでもおまけ程度の位置づけです。例題番号的にこの位置にしましたが、結果的にちょっとややこしい内容のものが含まれています。それゆえ、初心者の方は「Rだとこんな感じでできる」ことを実感する程度の位置づけでよいと思います。もう少し真面目に解説すると、strsplit
関数の出力がリスト形式とよばれるもので、そこから情報を取り出す際に大括弧(角括弧)が2つ並んだ[[1]]
のような感じで情報を取り出しています。この場合は配列が1つしかないので、[[1]]
として1番目の要素を取り出しています。
param <- "AC"
hoge <- strsplit(fasta, param)[[1]]
## Warning in .normarg_at2(at, x): 'at' names were ignored
以下では、hoge
の中身を表示しています。hoge
の中身と例題1.1の解答例を見比べればわかりますが、ACで分割後の配列数(=5)が一致していることがわかります。また、2番目以降の配列の冒頭にACが付加されていないことがわかりますが、これはstrsplit
関数の性質上やむを得ません。もしかしたら制限酵素認識配列専用の関数を誰かが作っているのかもしれませんが、実用上は自分が知っている関数の中から近い機能を果たすものをうまく使い、残りはad
hoc(その場しのぎ、のようなイメージでよいです)に対応するという感じでよいと思います。
hoge
## DNAStringSet object of length 5:
## width seq
## [1] 3 TTG
## [2] 15 AATTTCCTGATTCGG
## [3] 5 GTCCC
## [4] 20 TATATCATATGAATCCCTCA
## [5] 9 TCTATTGCA
ad
hocな対応の例として、たとえばwidth(hoge)
とやることで、hoge
オブジェクト中の計5配列の長さ情報を数値ベクトルとして得ることができます。
width(hoge)
## [1] 3 15 5 20 9
また、今は仮想制限酵素が2塩基だとわかっていますので、以下のようにwidth(hoge) + 2
とすることで、ベクトル中の全要素に2を足すことができます。
width(hoge) + 2
## [1] 5 17 7 22 11
上記は、param
オブジェクトの中身が2文字から構成されることが分かっているのでそのまま2としました。もちろんもう少し一般性を高めた表現も可能です。例えば、オブジェクト中の文字数をカウントするnchar
関数を用いて、nchar(param)
として利用することもできます。こんな感じで少しずつRの関数に慣れていくとよいでしょう。
nchar(param)
## [1] 2
width(hoge) + nchar(param)
## [1] 5 17 7 22 11
ただ上記の結果だと、最初の要素にまで2が足されてしまっています。それゆえ、何を足すかという情報をあらかじめ作成しておいてから、width(hoge)
の対応する要素と足し合わせるようなことをすればよいです。この場合は、1番目が0、2-5番目の要素が2の計5つの要素からなる数値ベクトルを作成して足すようなイメージです。rep
関数は、1番目の引数として指定した情報を、2番目の引数で指定した個数だけ複製(replicate)します。以下では、rep(2, 4)
として2
を4
つ作成しています。引数名を明示すると、rep(x=2, times=4)
と書くこともできます。
rep(2, 4)
## [1] 2 2 2 2
以下は、rep(nchar(param), 4)
として、実質的に中身が2のnchar(param)
にしているだけです。どちらでもいいじゃないかと思われるかもしれませんが、こんな感じで一般式で書くことによって手作業で変更せねばならないところを極力減らして汎用性を高めていきます。
rep(nchar(param), 4)
## [1] 2 2 2 2
以下では、ベクトルを連結(combine)するc
関数を用いて、最初の要素が0、2番目以降が2という数値ベクトルを連結させて得たものをtasuyou
というオブジェクトに格納しています。ここまでで、width(hoge)
の対応する要素に足すべき数値が格納されたtasuyou
オブジェクトの完成です。Rの教え方はヒトそれぞれですが、このあたりを見るだけでも基本テクの習得が重要であることがわかると思います。
tasuyou <- c(0, rep(nchar(param), 4))
tasuyou
## [1] 0 2 2 2 2
残りは、width(hoge)
とtasuyou
の対応する要素を以下のように足せばよいです。ここまでで例題1.1の解答例の最後に示した光学マップ情報が得られたことになります。
width(hoge) + tasuyou
## [1] 3 17 7 22 11
上記項目の続きですが、RStudio起動直後の状態でも、以下を実行すれば必要な情報を取得できます。この項目の主目的は、replaceAt
関数の紹介や、as.character
関数実行結果オブジェクトの取り扱いに関する小技の伝授です。なお、strsplit
関数実行部分で「Warning in .normarg_at2(at, x): 'at' names were ignored
」という警告メッセージが表示されていますが、エラーではないので気にする必要はありません。
in_f <- "R1.080.fasta"
param <- "AC"
library(Biostrings)
fasta <- readDNAStringSet(in_f, format="fasta")
hoge <- strsplit(fasta, param)[[1]]
## Warning in .normarg_at2(at, x): 'at' names were ignored
AC
で分割された配列からなるhoge
オブジェクト中の各配列に対して、1
番目の塩基の位置にparam
で指定した塩基(つまりAC
)を挿入することもできます。これも本当は2番目以降の配列のみに挿入したいのですが、ややこしくなるのでreplaceAt
という関数を用いればこういうこともできるんだという程度の情報にとどめておきます。以下では、param
,
hoge
,
replaceAt(hoge, 1, value=param)
の実行結果を一気に表示しています。背景が灰色になっている部分がコマンド、##から始まっている背景が白くなっている部分が実行結果です。
param
## [1] "AC"
hoge
## DNAStringSet object of length 5:
## width seq
## [1] 3 TTG
## [2] 15 AATTTCCTGATTCGG
## [3] 5 GTCCC
## [4] 20 TATATCATATGAATCCCTCA
## [5] 9 TCTATTGCA
replaceAt(hoge, 1, value=param)
## DNAStringSet object of length 5:
## width seq
## [1] 5 ACTTG
## [2] 17 ACAATTTCCTGATTCGG
## [3] 7 ACGTCCC
## [4] 22 ACTATATCATATGAATCCCTCA
## [5] 11 ACTCTATTGCA
strsplit
関数の入力は、入力が塩基配列であることを明示したDNAStringSet
形式のfasta
オブジェクトではなく、ただの文字列(as
character)としたものを与えることもできます。この場合は、as.character(fasta)
を入力とすればよいです。
fasta
## DNAStringSet object of length 1:
## width seq names
## [1] 60 TTGACAATTTCCTGATTCGGACG...ATGAATCCCTCAACTCTATTGCA fig1.8a
as.character(fasta)
## fig1.8a
## "TTGACAATTTCCTGATTCGGACGTCCCACTATATCATATGAATCCCTCAACTCTATTGCA"
以下を実行して得られる、出力結果のhoge2
を眺めると、$fig1.8a
というのが最初のほうに見えていて気持ち悪いと思われるかもしれません。慣れてくると、こういうの見た段階でhoge2$fig1.8a
のような感じで取り扱えばよいと閃くことができるようになります。
hoge2 <- strsplit(as.character(fasta), param)
hoge2
## $fig1.8a
## [1] "TTG" "AATTTCCTGATTCGG" "GTCCC"
## [4] "TATATCATATGAATCCCTCA" "TCTATTGCA"
たとえば、hoge2
で見えている計5配列の配列長を調べたい場合は、hoge2$fig1.8a
を入力として、文字数をカウントするnchar
関数を実行すればよいです。
nchar(hoge2$fig1.8a)
## [1] 3 15 5 20 9
また、見慣れたDNAStringSet
形式にしたい場合は、hoge2$fig1.8a
を入力として、DNAStringSet
関数を実行すればよいです。
DNAStringSet(hoge2$fig1.8a)
## DNAStringSet object of length 5:
## width seq
## [1] 3 TTG
## [2] 15 AATTTCCTGATTCGG
## [3] 5 GTCCC
## [4] 20 TATATCATATGAATCCCTCA
## [5] 9 TCTATTGCA
readDNAStringSet
関数で読み込めますが、gff3のほうがダメなので全部解凍しといたほうがややこしくないと思います)。上記の情報はEnsemblBacteria (Release 54)のものですが、リリースの違いによってリンク切れになったりします。それゆえ、以降の解析が数年後でも可能となるよう、念のため以下でも解凍後のファイルへのリンクを貼っておきます:
readDNAStringSet
ではなくreadAAStringSet
にせねばなりません。1.10.2項で述べた、アノテーション結果を格納する代表的な形式であるGFF3ファイルをRStudioで読み込むやり方を示します。rtracklayerパッケージ(Lawrence et al.,
Bioinformatics, 2009)が提供するreadGFF
関数や、GenomicsFeatures(Lawrence et al., PLoS
Comput Biol.,
2013)が提供するmakeTxDbFromGFF
関数がありますが、ここでは後者のやり方を示します。GenomicsFeaturesを未インストールの方は、まず以下を実行してください。
BiocManager::install("GenomicFeatures", update=F)
次に、GenomicsFeatures(Lawrence et al., PLoS
Comput Biol.,
2013)が提供するmakeTxDbFromGFF
関数を用いて、Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3を入力として読み込むやり方を示します。背景が灰色になっている計4行から構成される以下のコマンドでは、まず入力ファイルをin_fというオブジェクト名で取り扱うという宣言をしています。次に、GenomicsFeaturesパッケージをlibrary
関数を用いてロードしています。これでGenomicFeaturesが提供する関数を利用可能になったので、(入力ファイル名に相当する)in_f
を入力としてmakeTxDbFromGFF
関数を実行した結果をtxdb
というオブジェクトに格納し、その中身を表示しています。
in_f <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3"
library(GenomicFeatures)
## Error in library(GenomicFeatures): 'GenomicFeatures' という名前のパッケージはありません
txdb <- makeTxDbFromGFF(in_f, format="auto")
## Error in makeTxDbFromGFF(in_f, format = "auto"): 関数 "makeTxDbFromGFF" を見つけることができませんでした
txdb
## Error in eval(expr, envir, enclos): オブジェクト 'txdb' がありません
背景が白の実行結果の冒頭部分にTxDb object
と書かれていることと、makeTxDbFromGFF
関数を実行した結果であることから想像できるように、makeTxDbFromGFF
関数はGFF形式ファイルを読み込んでTxDbというGenomicsFeaturesパッケージ内で有効な独特の形式でGFF情報を格納しているのだと理解すればよいです。重要なことは、無事に読み込めることと、txdbの中身に相当する背景が白の実行結果から見られる情報として「Nb of transcripts: 3236
」に注目することです。この3236という数値は、確かにダウンロード元であるLactobacillus
casei 21/1から辿れるMore
information and statisticsで見られるGene
transcriptsの数と一致しています。GFFファイル自体は1つしかないため、すべての情報を含んでないと都合が悪いのだと考えれば納得できると思います。念のために以下にもリンク先のスクショを示しておきます。①の部分の数値と一致しているということです。
TxDb object
であるtxdb
オブジェクトだけを見せられても実感がわかないと思います。txdb
の中に含まれているのは、ゲノム配列中のどこにどのようなフィーチャ(アノテーションがつけられるゲノム上の各領域のこと)があるのかという座標情報です。たとえばtxdb
を入力としてtranscripts
関数を実行すると、GRanges object
という形式の、この場合はtranscripts
なので転写物の座標情報を得ることができます。
seqnames
列は、アノテーションに用いた大元のゲノム配列ファイル(Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa)内のdescription行で見られる配列名情報に相当します。1番目の転写物はctg01_00128
という配列上、3236番目の転写物はctg75_00141
という配列上に存在するものだと解釈します。ctg
は、コンティグ(contig)を意味します。最もよくつながっているのが染色体レベル、その前段階がスカッフォールドレベル、そしてコンティグレベルとなります。この乳酸菌ゲノムは全部で75配列から構成されますが、バクテリア程度のゲノムサイズで75配列に分断されている程度のアセンブリ結果しか得られていないので、ある程度業界歴が長くなると「確かにコンティグレベルだろうな」というのがわかってきます。
ranges
列はstartとendの位置情報、strand
列は+鎖か-鎖のどちらかの情報、tx_id
列は転写物のシリアル番号、tx_name
列は転写物名を表しています。
in_f <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3"
library(GenomicFeatures)
## Error in library(GenomicFeatures): 'GenomicFeatures' という名前のパッケージはありません
txdb <- makeTxDbFromGFF(in_f, format="auto")
## Error in makeTxDbFromGFF(in_f, format = "auto"): 関数 "makeTxDbFromGFF" を見つけることができませんでした
transcripts(txdb)
## Error in transcripts(txdb): 関数 "transcripts" を見つけることができませんでした
ノリさえわかってくれば、txdb
を入力としてpromoters
関数を実行することでプロモータ配列を取得することもできます。以下は、転写開始点(TSS)の上流50
塩基、下流10
塩基の領域情報を取得するコマンドです。たとえば1番目の転写物のTSSは、ctg01_00128
という配列の4769
番目の塩基です(+鎖なので、start位置がTSSです)。この転写物のプロモータ領域は4719-4778
となっていますが、確かにTSSである4769
- 50 = 4719、そして4769 + 10 - 1 =
4778で妥当な結果です。もう1つの例として、3236番目の転写物物は-鎖上にあるので、転写開始点(TSS)はctg75_00141
という配列の639
番目の塩基になります。それゆえ、上流50
塩基は639
+ 50 = 689番目の塩基、そして下流10
塩基は639 - 10 + 1 =
630番目の塩基になります。したがって、取得したプロモータ領域は妥当です。
in_f <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3"
library(GenomicFeatures)
## Error in library(GenomicFeatures): 'GenomicFeatures' という名前のパッケージはありません
txdb <- makeTxDbFromGFF(in_f, format="auto")
## Error in makeTxDbFromGFF(in_f, format = "auto"): 関数 "makeTxDbFromGFF" を見つけることができませんでした
promoters(txdb, upstream=50, downstream=10)
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'promoters' に対するメソッドの選択時): オブジェクト 'txdb' がありません
ここでは、実際に取得した座標情報であるGRanges object
を利用して、その領域の塩基配列を取得します。ただし、GFF3ファイルの情報はただの座標情報にすぎないため、大元のGFF3ファイルと対応したゲノム配列も読み込んで利用せねばならない点に注意が必要です。ここではアノテーションに用いた大元のゲノム配列ファイル(Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa)も同時に読み込んでin_f1というオブジェクト名で利用しています。Rsamtoolsパッケージが提供するgetSeq
やFaFile
関数も利用します。Rsamtoolsを未インストールの方は、まず以下を実行してください。
BiocManager::install("Rsamtools", update=F)
以下は、アノテーションのGFF3形式ファイルとゲノム配列のFASTA形式ファイルの2つを入力として与えて、最終的にDNAStringSeq
形式のfasta
オブジェクトを得るところまでのコードです。計3つのパッケージを明示的にロードしていることがわかります。実際問題としては依存関係的に明示する必要がないものもあるかもしれませんが、(ロードしておいて文句を言われることとパッケージをロードしていないことに起因するエラーを天秤にかけて)念のためにlibrary
関数を用いてロードしています。なお、library
の代わりにrequire
関数を使われる方もいらっしゃいますが、実用上はどちらでも構いません。makeTxDbFromGFF
関数でGFF3ファイル名に相当するin_f2を読み込んだ結果をtxdb
オブジェクトに格納し、transcripts
関数で転写物の座標情報をGRanges
形式のhoge
オブジェクトに格納しています。最後に「ゲノム配列ファイルに相当するin_f1
」と「先ほどのGFF3形式ファイルの中身に相当するhoge
オブジェクト」の2つを入力としてgetSeq
関数を実行することで、目的のDNAStringSeq
形式のfasta
オブジェクトを得ることができます。
##から始まっている背景が白くなっている実行結果部分を見ると、確かにfasta
オブジェクトはDNAStringSeq
形式になっていることがわかります。width
列は配列長情報で、たとえば1番最初の転写物の配列長は1086です。この転写物のGRanges
形式のstartとendの位置は4769-5854
ですので、5,854
- 4769 + 1 =
1,086なので妥当だと判断できます。ここでは表示していませんが、気になるかたはtranscripts(txdb)
実行結果に相当するhoge
オブジェクトの中身を表示させて確認してみるとよいと思います。
in_f1 <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa"
in_f2 <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3"
library(Rsamtools)
library(GenomicFeatures)
## Error in library(GenomicFeatures): 'GenomicFeatures' という名前のパッケージはありません
library(Biostrings)
txdb <- makeTxDbFromGFF(in_f2, format="auto")
## Error in makeTxDbFromGFF(in_f2, format = "auto"): 関数 "makeTxDbFromGFF" を見つけることができませんでした
hoge <- transcripts(txdb)
## Error in transcripts(txdb): 関数 "transcripts" を見つけることができませんでした
fasta <- getSeq(FaFile(in_f1), hoge)
## Error in (function (classes, fdef, mtable) : 関数 'scanFa' (シグネチャ '"FaFile", "DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
fasta
## DNAStringSet object of length 1:
## width seq names
## [1] 60 TTGACAATTTCCTGATTCGGACG...ATGAATCCCTCAACTCTATTGCA fig1.8a
以下は、得られた転写物配列情報をFASTA形式ファイルとして保存するところまで含めたスクリプトです。上のスクリプトとの違いは、3行目の出力ファイル名情報を格納するためのout_f
オブジェクト作成部分と、最後から2番目の行のwriteXStringSet
関数実行部分です。無事実行完了すると、出力ファイル名として指定したファイル(R1.130.1.fasta)が作成されているはずです。ここまでで配列取得の基本形はが完成です。なお、最終行のfasta[1:4]
は、「fastaオブジェクト中の最初の4配列分を表示せよ」という意味です。これはhead(fasta, n=4)
というコマンドと同じです。head
は最初のn個分(デフォルトは6)を出力する関数であるため、n=4
として最初の4個分とオプションで指定していることに相当します。
in_f1 <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa"
in_f2 <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3"
out_f <- "R1.130.1.fasta"
library(Rsamtools)
library(GenomicFeatures)
## Error in library(GenomicFeatures): 'GenomicFeatures' という名前のパッケージはありません
library(Biostrings)
txdb <- makeTxDbFromGFF(in_f2, format="auto")
## Error in makeTxDbFromGFF(in_f2, format = "auto"): 関数 "makeTxDbFromGFF" を見つけることができませんでした
hoge <- transcripts(txdb)
## Error in transcripts(txdb): 関数 "transcripts" を見つけることができませんでした
fasta <- getSeq(FaFile(in_f1), hoge)
## Error in (function (classes, fdef, mtable) : 関数 'scanFa' (シグネチャ '"FaFile", "DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
writeXStringSet(fasta, file=out_f, format="fasta", width=50)
fasta[1:4]
## Error: subscript contains out-of-bounds indices
さきほどのファイル(R1.130.1.fasta)のdescription行に相当する情報は、上で見えているfasta
オブジェクトのnames
列です。“ctg01_00128”は、計75配列からなるゲノム配列ファイル(Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa)の1番最初の配列名です。この情報は、(計3,236配列分あるので画面がざっと流れますが)names(fasta)
で一望できます。元のゲノム配列は計75配列(75
contigs)から構成されていますので、種類としては計75種類ということになります。どのコンティグ由来配列が何個あったかは、計3,236要素からなる文字列ベクトルであるnames(fasta)
を入力として、以下のようにtable
関数を実行すればよいです。実行結果は、たとえば”ctg01_00128”というコンティグ由来転写物は38個、“ctg02_00001”由来の転写物は17個という風に解釈します。
table(names(fasta))
##
## fig1.8a
## 1
配列取得1では、転写物配列取得の基本形を示しました。以下は、先ほどの配列取得1の出力ファイル(R1.130.1.fasta)を得るスクリプトの再掲です。hoge
はtranscripts(txdb)
実行結果のGRanges形式のオブジェクト、fasta
はhoge
の情報を用いて転写物配列を取得したDNAStringSet形式のオブジェクトです。
in_f1 <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa"
in_f2 <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3"
out_f <- "R1.130.1.fasta"
library(Rsamtools)
library(GenomicFeatures)
## Error in library(GenomicFeatures): 'GenomicFeatures' という名前のパッケージはありません
library(Biostrings)
txdb <- makeTxDbFromGFF(in_f2, format="auto")
## Error in makeTxDbFromGFF(in_f2, format = "auto"): 関数 "makeTxDbFromGFF" を見つけることができませんでした
hoge <- transcripts(txdb)
## Error in transcripts(txdb): 関数 "transcripts" を見つけることができませんでした
fasta <- getSeq(FaFile(in_f1), hoge)
## Error in (function (classes, fdef, mtable) : 関数 'scanFa' (シグネチャ '"FaFile", "DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
writeXStringSet(fasta, file=out_f, format="fasta", width=50)
以下は、hoge
オブジェクトの最初の3行分を表示させた結果です。最初の2列(seqnames
とranges
列)は、その列名を関数として情報抽出に利用できます。
hoge[1:3]
## DNAStringSet object of length 3:
## width seq
## [1] 3 TTG
## [2] 15 AATTTCCTGATTCGG
## [3] 5 GTCCC
以下は、fasta
オブジェクトの最初の3行分を表示させた結果です。names
列の情報に相当するnames(fasta)
は、hoge
オブジェクトのseqnames
列の情報と同じであることがわかります。
fasta[1:3]
## Error: subscript contains out-of-bounds indices
以下は、seqnames(hoge)
の実行結果です。見慣れないと面食らってしまうかもしれませんが、先程のtable(names(fasta))
実行結果と見比べれば、「ctg01_00128が38個ある」や「ctg02_00001が17個ある」といったことがわかります。ここでは示しませんが、table(names(fasta))
の実行結果は、table(seqnames(hoge))
の実行結果と同じです。また、names(fasta)
と同じ見栄えの情報は、as.character(seqnames(hoge))
で得られます。さらに、table(seqnames(hoge))
と同じ結果は、table(as.character(seqnames(hoge)))
でも得られます。いきなりtable(as.character(seqnames(hoge)))
を見ると難解だと思うかもしれませんが、このように様々な情報と照らし合わせて、要素ごとに分解して眺めると理解しやすいのではと思います。
seqnames(hoge)
## Error in (function (classes, fdef, mtable) : 関数 'seqnames' (シグネチャ '"DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
次は、ranges(hoge)
の実行結果です。確かにhoge
オブジェクト中のranges
列で見えている情報が含まれています。start
列とend
列に加えてwidth
列が見えていますが、これは(end
- start +1)で算出される配列長情報です。
ranges(hoge)
## Error in (function (classes, fdef, mtable) : 関数 'ranges' (シグネチャ '"DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
ranges(hoge)
の実行結果で見えている情報は、その列名を関数として当該列情報を抽出できます。具体的には、start
列の情報はstart(ranges(hoge))
、end
列の情報はend(ranges(hoge))
、そしてwidth
列の情報はwidth(ranges(hoge))
で取得可能です。以下では、(これをそのまま実行してしまうと、それぞれについて計3,236配列分の要素の情報が一気に表示されて見づらいため)さらにhead
関数をつけて最初の6個分に限定して示します。
head(start(ranges(hoge)))
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'head' に対するメソッドの選択時): 引数 'x' の評価中にエラーが起きました (関数 'start' に対するメソッドの選択時): 関数 'ranges' (シグネチャ '"DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
head(end(ranges(hoge)))
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'head' に対するメソッドの選択時): 引数 'x' の評価中にエラーが起きました (関数 'end' に対するメソッドの選択時): 関数 'ranges' (シグネチャ '"DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
head(width(ranges(hoge)))
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'head' に対するメソッドの選択時): 引数 'x' の評価中にエラーが起きました (関数 'width' に対するメソッドの選択時): 関数 'ranges' (シグネチャ '"DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
ここで、再度転写物配列情報であるfasta
オブジェクトの最初の5行分を表示させます。names
列の情報に相当するnames(fasta)
はR1.130.1.fastaのdescription行に相当しますが、現状では由来配列名しか示されていないことがわかります。
fasta[1:5]
## Error: subscript contains out-of-bounds indices
そこで、これまで示してきたテクニック+αで、names(fasta)
の情報を「由来配列名」から「由来配列名_start_end」に変更し、転写物配列がどの配列のどの領域由来かがdescription情報をみればわかるようにします。まず、新たな関数としてpaste
を紹介します。paste
は、複数の数値なり文字なりを、任意の文字や記号で連結する関数です。以下に4つ例を示します。最後のコマンドが実際にやろうとしていることに近いものになります。
paste(8, 5, sep="_")
## [1] "8_5"
paste("an", 5, "pan", sep="__")
## [1] "an__5__pan"
paste("an", "pon", "tan", sep="")
## [1] "anpontan"
paste(head(start(ranges(hoge))), head(end(ranges(hoge))), sep="_")
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'head' に対するメソッドの選択時): 引数 'x' の評価中にエラーが起きました (関数 'start' に対するメソッドの選択時): 関数 'ranges' (シグネチャ '"DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
ここから本番になっていきますが、まずは変更前のnames(fasta)
の最初の6個分の情報を以下に示します。
head(names(fasta))
## [1] "fig1.8a"
以下が、names(fasta)
の情報を「由来配列名」から「由来配列名_start_end」に変更する本番のコマンドです。あまり横長になっても見づらいので2つの行にわけていますが、paste
関数を使って、当該転写物の由来配列名に相当する情報のseqnames(hoge)
、当該転写物のstart位置に相当する情報のstart(ranges(hoge))
、そして当該転写物のend位置に相当する情報のend(ranges(hoge))
を”_“で連結した結果を、names(fasta)
に格納(代入)しています。ここでは右辺の情報を統一的にhoge
オブジェクトに揃える目的で由来配列名に相当する情報としてseqnames(hoge)
を用いましたが、names(fasta)
で置き換えてもかまいません。その場合は、右辺のnames(fasta)
が「由来配列名」のみに相当し、左辺のnames(fasta)
が変更後の「由来配列名_start_end」ということになります。
names(fasta) <- paste(seqnames(hoge), start(ranges(hoge)),
end(ranges(hoge)), sep="_")
## Error in (function (classes, fdef, mtable) : 関数 'seqnames' (シグネチャ '"DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
変更後のnames(fasta)
の最初の6個分の情報を以下に示すべく、以下で再度head(names(fasta))
実行結果を示します。確かに意図通りにstartとendの情報が右側に追加されていることがわかります。
head(names(fasta))
## [1] "fig1.8a"
注意点としては、fasta
オブジェクトの中身がこの段階で変更されているということです。つまりこの場合は、names
列の情報が変更されています。右端が…になっているものがありますが、上のほうで見えている結果を突き合わせることで意図通りに変更されていると確信できると思います。
fasta
## DNAStringSet object of length 1:
## width seq names
## [1] 60 TTGACAATTTCCTGATTCGGACG...ATGAATCCCTCAACTCTATTGCA fig1.8a
最後に、names(fasta)
の情報を更新したものをファイル(R1.130.2.fasta)に保存するところまでの一連のスクリプトを示します。最終行のfasta[1:3]
の実行結果を見れば、確かに出力ファイルのdescription行が正しく変更されていると確信できると思います。
in_f1 <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa"
in_f2 <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3"
out_f <- "R1.130.2.fasta"
library(Rsamtools)
library(GenomicFeatures)
## Error in library(GenomicFeatures): 'GenomicFeatures' という名前のパッケージはありません
library(Biostrings)
txdb <- makeTxDbFromGFF(in_f2, format="auto")
## Error in makeTxDbFromGFF(in_f2, format = "auto"): 関数 "makeTxDbFromGFF" を見つけることができませんでした
hoge <- transcripts(txdb)
## Error in transcripts(txdb): 関数 "transcripts" を見つけることができませんでした
fasta <- getSeq(FaFile(in_f1), hoge)
## Error in (function (classes, fdef, mtable) : 関数 'scanFa' (シグネチャ '"FaFile", "DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
names(fasta) <- paste(seqnames(hoge), start(ranges(hoge)),
end(ranges(hoge)), sep="_")
## Error in (function (classes, fdef, mtable) : 関数 'seqnames' (シグネチャ '"DNAStringSet"' に対する) に対する継承メソッドを見付けることができません
writeXStringSet(fasta, file=out_f, format="fasta", width=50)
fasta[1:3]
## Error: subscript contains out-of-bounds indices
上記の情報はEnsemblBacteria (Release 54)のものですが、リリースの違いによってリンク切れになったりします。それゆえ、以降の解析が数年後でも可能となるよう、念のため以下でもファイルへのリンクを貼っておきます。“Lactobacillus_casei_21_1_gca_000309585.ASM30958v1”までが共通で、それ以降の文字列が異なっていることがわかります。たとえば1-2番目のファイルはは”dna”、3-4番目のファイルは”dna_rm”、そして5-6番目のファイルは”dna_sm”となっていることがわかります。“dna”はマスクされていない配列(unmasked)のことです。“dna_rm”は、RepeatMaskerで同定された反復配列をマスクした(masked)配列のことで、具体的には”N”で置換した配列のことです。“dna_sm”は、RepeatMaskerで同定された反復配列をソフトにマスクした(soft-masked)配列のことです。その次のnonchromosomalは、当該ゲノムの配列決定レベル(解像度)が最高の染色体レベルになったとしても、どの染色体にも割り当てられない断片配列が存在しますので、それらの配列も含めたものです。toplevelは、当該ゲノムの最高の配列決定レベルで得られた配列から構成されるファイルです。この場合は、配列決定精度がコンティグレベル(contig; ctg)ですので、nonchromosomalとtoplevelの中身は同じになります。直感的には、最も”N”が少ないのが”dna”、最も多いのが”dna_rm”です。また、最も”ACGTN”以外の文字が多いのが”dna_sm”ということになります。
soft-maskedがわかりづらいかもしれませんが、これは塩基配列の表記法(nomenclature)はA, C, G, T, Nの5種類だけではないという事実を正しく理解するところからスタートせねばなりません。たとえばプリン塩基(A or G)であることが確かなら、1文字表記のRとします。同様に、ピリミジン塩基(C or T)であることが確かならYです。他にもありますので、全体像を以下にまとめておきます。なお、元情報は1984年に勧告された命名法の論文(Cornish-Bowden A., Nucleic Acids Res., 1985)中のTable 1です。
塩基 | 1文字表記 | 表記の由来 |
---|---|---|
A or C | M | aMino |
A or G | R | puRine |
A or T | W | Weak interaction (2 H bonds) |
C or G | S | Strong interaction (3 H bonds) |
C or T | Y | pYrimidine |
G or T | K | Ketone |
A or C or G | V | not-T (not-U), V follows U in the alphabet |
A or C or T | H | not-G, H follows G in the alphabet |
A or G or T | D | not-C, D follows C in the alphabet |
C or G or T | B | not-A, B follows A in the alphabet |
A or C or G or T | N | aNy |
先程までGFF3ファイルであるLactobacillus_casei_21_1_gca_000309585.ASM30958v1.49.gff3とともに読み込んで、転写物配列ファイル(R1.130.2.fasta)作成の元データとして用いたのは、Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.faです。以下ではまず、Biostringsパッケージが提供するreadDNAStringSet
関数がgzip圧縮ファイルでも読み込めることを示します。DNAStringSeq
形式のfasta
オブジェクトのwidth
列とnames
列を見比べることで、width
列の配列長で降順(多–>少)にコンティグ(contig;
ctg)が並べられていることがわかります。
in_f <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa.gz"
library(Biostrings)
fasta <- readDNAStringSet(in_f, format="fasta")
fasta
## DNAStringSet object of length 75:
## width seq names
## [1] 362642 GAGGACGCGCACGTGGGCCGTG...CGGTGCTCGCGATATCTGAGTC ctg27_00064 dna:s...
## [2] 208498 AAAACCTGCACATAAAGGACCT...CTAATACCGCATAGATCCAAGA ctg15_00035 dna:s...
## [3] 157092 GTCAAAGGCTGCTGTTTGACCA...CTTGATGAAGCTGAACTGCCCG ctg40_00041 dna:s...
## [4] 145075 AGCTGATGAGCCAGCATTAATG...TATTCGCGTAGTTAGGTGGTCG ctg05_00082 dna:s...
## [5] 137019 TAGAAGCTACTGTATTGGACAG...AAGACCTGTTTTGCTTGGTGGT ctg49_00090 dna:s...
## ... ... ...
## [71] 2084 GAGACGAGGCGATTCGGATTGA...CTCGCGATATCTGAGTCGGAGA ctg68_00104 dna:s...
## [72] 2082 CCCCATTGAGGACGCGCACGTG...TGGTTGCGGCAATTCGTGATAC ctg22_00049 dna:s...
## [73] 1899 TGTTCCTTCTCCCTCGATCCAC...GCATCGTGGAGCTCAATTGAAT ctg62_00065 dna:s...
## [74] 1186 AATCAGTGGTTTTAACACTTTG...CCATCAGTCTTGCAAATCCCTT ctg72_00112 dna:s...
## [75] 981 AAGCTAATCTCTTAAAGCCATT...GAAGAGCCCAAACCGAGAAGCT ctg67_00088 dna:s...
ちなみに、width(fasta)
とやることで、配列(この場合はコンティグ)ごとの配列長情報を取得することができます。計75配列あるので、この出力結果は75個の要素からなる数値ベクトルです。1番左側に[1]や[11]や[21]が見えていますが、これは要素番号情報です。たとえば、表示されている数値ベクトルの1番目の要素が362642、11番目の要素が84732、21番目の要素が54844なのだと解釈します。
width(fasta)
## [1] 362642 208498 157092 145075 137019 129187 108667 108303 97079 85220
## [11] 84732 82851 77549 73381 71270 63087 62872 61538 60645 55203
## [21] 54844 53115 52123 44573 44411 39905 36629 35796 34344 33427
## [31] 31565 30996 28708 27489 27063 26659 25214 23894 22582 21546
## [41] 20833 19583 15729 15495 15347 14920 14532 14456 13971 12665
## [51] 11741 9875 8984 8827 8373 8327 7299 6625 6268 5549
## [61] 5013 4984 4879 4541 4450 4427 4314 3561 2803 2482
## [71] 2084 2082 1899 1186 981
R1.100
1.10.2項のGFF3(ファイル取得)のところで、「③より、このゲノムサイズは3,215,878
bp」と書いています。この数値は、以下のように計75配列の配列長が格納された数値ベクトルであるwidth(fasta)
を入力として、ベクトルの総和を計算するsum
関数を実行することで確認できます。
sum(width(fasta))
## [1] 3215878
DNAStringSeq
形式のfasta
オブジェクトを入力としてalphabetFrequency
関数を実行すると、fasta
オブジェクトの各配列に対して、塩基の種類ごとの出現頻度を返してくれます。ただ、もしalphabetFrequency(fasta)
としてしまうと、A,
C, G, T, Nだけでなく、上記の表で示したような「プリン塩基(A or
G)ならR」、「ピリミジン塩基(C or
T)ならY」といったような様々な結果が配列ごとに一気に表示されてしまい見づらくなってしまいます。そのため、以下ではbaseOnly=TRUE
というオプションをつけて「A,
C, G, Tとそれ以外」という5種類に要約して表示させています。
alphabetFrequency(fasta, baseOnly=TRUE)
## A C G T other
## [1,] 96419 90508 78914 96785 16
## [2,] 55574 45928 51916 55056 24
## [3,] 42001 38922 33789 42380 0
## [4,] 39472 31070 35781 38752 0
## [5,] 37540 32735 29815 36893 36
## [6,] 34247 27717 32885 34337 1
## [7,] 28507 23670 27141 29343 6
## [8,] 28990 23437 26900 28968 8
## [9,] 25883 20792 24303 26101 0
## [10,] 22368 18160 21896 22796 0
## [11,] 22733 20836 18295 22865 3
## [12,] 21759 20859 18548 21682 3
## [13,] 21351 18971 16625 20600 2
## [14,] 20306 15136 17718 20219 2
## [15,] 19105 17766 15239 19158 2
## [16,] 17446 15108 12820 17712 1
## [17,] 16225 15014 14799 16833 1
## [18,] 16366 15551 13489 16132 0
## [19,] 16842 13238 15045 15520 0
## [20,] 15124 11638 13701 14740 0
## [21,] 16161 11516 11904 15231 32
## [22,] 13991 12821 11694 14607 2
## [23,] 13602 12982 11532 14007 0
## [24,] 11933 10183 10502 11955 0
## [25,] 11299 9461 10991 12660 0
## [26,] 10522 10154 8673 10555 1
## [27,] 10198 7654 8813 9964 0
## [28,] 9490 7728 8673 9901 4
## [29,] 9035 7599 8337 9373 0
## [30,] 8910 8529 7174 8813 1
## [31,] 9705 6549 7610 7701 0
## [32,] 7701 7901 6785 8599 10
## [33,] 7323 6110 7427 7848 0
## [34,] 7266 6970 6098 7155 0
## [35,] 7413 6668 5876 7104 2
## [36,] 6917 6590 6032 7120 0
## [37,] 7460 5231 5738 6768 17
## [38,] 7083 5545 4640 6626 0
## [39,] 6424 4932 4768 6440 18
## [40,] 5332 5061 4639 6511 3
## [41,] 4863 5826 5688 4446 10
## [42,] 5925 3718 4271 5664 5
## [43,] 4413 3538 3821 3956 1
## [44,] 4098 3884 3499 4012 2
## [45,] 3946 3203 3812 4386 0
## [46,] 4038 3874 3265 3743 0
## [47,] 4032 3341 3726 3433 0
## [48,] 3903 3348 3456 3748 1
## [49,] 3818 3481 2983 3687 2
## [50,] 3602 2627 2748 3684 4
## [51,] 3686 2201 2500 3352 2
## [52,] 2932 1720 1993 3230 0
## [53,] 2130 2294 2532 2024 4
## [54,] 2688 1769 1760 2604 6
## [55,] 2478 1751 1668 2476 0
## [56,] 2387 2020 1703 2217 0
## [57,] 2107 1563 1651 1978 0
## [58,] 1856 1510 1373 1874 12
## [59,] 1667 1339 1426 1836 0
## [60,] 1686 1047 1131 1685 0
## [61,] 1325 1191 1211 1281 5
## [62,] 1513 963 1126 1380 2
## [63,] 1379 996 1127 1377 0
## [64,] 1385 970 875 1306 5
## [65,] 1165 893 1120 1271 1
## [66,] 1192 991 977 1266 1
## [67,] 1139 969 964 1241 1
## [68,] 1045 831 644 1041 0
## [69,] 792 530 554 927 0
## [70,] 774 578 419 711 0
## [71,] 630 501 483 470 0
## [72,] 551 467 415 649 0
## [73,] 608 314 393 584 0
## [74,] 325 261 280 320 0
## [75,] 268 226 264 223 0
なお、baseOnly=TRUE
オプションをつけずにalphabetFrequency(fasta)
を実行した結果を、そのままcolSums
の入力として与えることで、入力配列全体のプリン塩基やピリミジン塩基の数がわかります。
in_f <- "Lactobacillus_casei_21_1_gca_000309585.ASM30958v1.dna.toplevel.fa.gz"
library(Biostrings)
fasta <- readDNAStringSet(in_f, format="fasta")
colSums(alphabetFrequency(fasta))
## A C G T M R W S Y K V
## 866369 741975 743383 863892 21 88 18 18 89 17 0
## H D B N - + .
## 0 0 0 8 0 0 0
page041の1行目で計算している171通りというのは、choose
関数で実行できます。
choose(19, 17)
## [1] 171
page047の図2.4aの再現を行います。まずは「(a)実データ」です。-log(p-value)の値が若干異なります(教科書では0.9248で、以下では0.9249234になっていると思います)。理由は不明ですが(単なる転記ミス?!)、まあ誤差範囲といえるでしょう。
data <- matrix(c(222, 86, 149, 228, 105, 124), nrow=3)
data
## [,1] [,2]
## [1,] 222 228
## [2,] 86 105
## [3,] 149 124
chisq.test(data)$p.value
## [1] 0.1188712
-log10(chisq.test(data)$p.value)
## [1] 0.9249234
次は「(a)仮想データ1」です。
data <- matrix(c(222, 106, 129, 228, 105, 124), nrow=3)
data
## [,1] [,2]
## [1,] 222 228
## [2,] 106 105
## [3,] 129 124
chisq.test(data)$p.value
## [1] 0.9123088
-log10(chisq.test(data)$p.value)
## [1] 0.03985815
次は「(a)仮想データ2」です。
data <- matrix(c(202, 86, 169, 228, 105, 124), nrow=3)
data
## [,1] [,2]
## [1,] 202 228
## [2,] 86 105
## [3,] 169 124
chisq.test(data)$p.value
## [1] 0.005590402
-log10(chisq.test(data)$p.value)
## [1] 2.252557
次は、表の中にはありませんが、本文中で述べている「実データを基本として全部10倍の罹患群4,570人
vs. 対照群4,570人」です。
data <- matrix(c(2220, 860, 1490, 2280, 1050, 1240), nrow=3)
data
## [,1] [,2]
## [1,] 2220 2280
## [2,] 860 1050
## [3,] 1490 1240
chisq.test(data)$p.value
## [1] 5.633341e-10
-log10(chisq.test(data)$p.value)
## [1] 9.249234
最後に「(b)」です。
data <- matrix(c(287, 149, 21, 292, 150, 15), nrow=3)
data
## [,1] [,2]
## [1,] 287 292
## [2,] 149 150
## [3,] 21 15
chisq.test(data)$p.value
## [1] 0.5925849
-log10(chisq.test(data)$p.value)
## [1] 0.2272494
page055の表2.1は、Bioconductorから提供されているBSgenome.Hsapiens.UCSC.hg19(ヒトゲノム配列のパッケージ)とTxDb.Hsapiens.UCSC.hg19.knownGene(上記ヒトゲノム配列パッケージに対応したアノテーション情報のパッケージ)を利用して作成しています。ここではまず、これら2つのパッケージをインストールします。圧縮して提供されているため、ヒトゲノムの一般的なイメージである3GBまではないにせよ、700MB程度はあります。したがって、インストールにはそれなりの時間がかかります(光のWifi環境で約5分とか…)。
BiocManager::install("BSgenome.Hsapiens.UCSC.hg19", update=F)
BiocManager::install("TxDb.Hsapiens.UCSC.hg19.knownGene", update=F)
ここではまず、表2.1aの1番左側の列で見えている2-merの並び情報をnarabi
オブジェクトとして定義し、必要なパッケージをロードします。
narabi <- c("AA", "AT", "TA", "TT", "CC", "CG", "GC", "GG",
"AC", "AG", "CA", "CT", "GA", "GT", "TC", "TG")
library(Biostrings) #パッケージのロード
library(BSgenome.Hsapiens.UCSC.hg19)#パッケージのロード
## Error in library(BSgenome.Hsapiens.UCSC.hg19): 'BSgenome.Hsapiens.UCSC.hg19' という名前のパッケージはありません
以下は、さきほどロードしたBSgenome.Hsapiens.UCSC.hg19と同名のオブジェクトをgenome
という名前に変更したのち、getSeq
関数でDNAStringSet object
形式のオブジェクトとして抽出した結果をfasta
に保存するまでのスクリプトです。最後にfasta
オブジェクトの配列名情報を与えるべく、seqnames(genome)
で代入しています。
#前処理(指定したパッケージ中のオブジェクト名をgenomeに統一)
genome <- BSgenome.Hsapiens.UCSC.hg19 #renameしているだけです
## Error in eval(expr, envir, enclos): オブジェクト 'BSgenome.Hsapiens.UCSC.hg19' がありません
fasta <- getSeq(genome) #ゲノム塩基配列情報を抽出した結果をfastaに格納
## Error in (function (classes, fdef, mtable) : 関数 'getSeq' (シグネチャ '"standardGeneric"' に対する) に対する継承メソッドを見付けることができません
names(fasta) <- seqnames(genome) #description情報を追加している
## Error in (function (classes, fdef, mtable) : 関数 'seqnames' (シグネチャ '"standardGeneric"' に対する) に対する継承メソッドを見付けることができません
fasta #確認してるだけです
## DNAStringSet object of length 75:
## width seq names
## [1] 362642 GAGGACGCGCACGTGGGCCGTG...CGGTGCTCGCGATATCTGAGTC ctg27_00064 dna:s...
## [2] 208498 AAAACCTGCACATAAAGGACCT...CTAATACCGCATAGATCCAAGA ctg15_00035 dna:s...
## [3] 157092 GTCAAAGGCTGCTGTTTGACCA...CTTGATGAAGCTGAACTGCCCG ctg40_00041 dna:s...
## [4] 145075 AGCTGATGAGCCAGCATTAATG...TATTCGCGTAGTTAGGTGGTCG ctg05_00082 dna:s...
## [5] 137019 TAGAAGCTACTGTATTGGACAG...AAGACCTGTTTTGCTTGGTGGT ctg49_00090 dna:s...
## ... ... ...
## [71] 2084 GAGACGAGGCGATTCGGATTGA...CTCGCGATATCTGAGTCGGAGA ctg68_00104 dna:s...
## [72] 2082 CCCCATTGAGGACGCGCACGTG...TGGTTGCGGCAATTCGTGATAC ctg22_00049 dna:s...
## [73] 1899 TGTTCCTTCTCCCTCGATCCAC...GCATCGTGGAGCTCAATTGAAT ctg62_00065 dna:s...
## [74] 1186 AATCAGTGGTTTTAACACTTTG...CCATCAGTCTTGCAAATCCCTT ctg72_00112 dna:s...
## [75] 981 AAGCTAATCTCTTAAAGCCATT...GAAGAGCCCAAACCGAGAAGCT ctg67_00088 dna:s...
以下は、表2.1の2列目の情報を得る部分のスクリプトです。まず、fasta
を入力としてalphabetFrequency
関数を実行し、配列ごとのACGT各塩基の出現頻度をカウントした結果をhoge
に格納しています。hoge
自体は、298行×18列からなる数値行列です。1行目がchr1、2行目がchr2といった感じで、配列ごとの結果が各行に格納されています。各列にはA,
C, G, T,
…の並びで塩基ごとのカウント結果が格納されています。それゆえ、colSums
関数を用いて列ごとの総和を計算してやれば、fasta
オブジェクト全体のAの数、Cの数、Gの数、Tの数の情報が得られます。実行結果であるfrequency
オブジェクトはベクトルであり、1番目の要素がAの数、2番目の要素がCの数、といった感じで格納されています。それゆえ、sum(frequency[2:3])/sum(frequency[1:4])
のような計算をしてあげれば、GC含量の情報(=
0.4101656)が得られるのです。expected
オブジェクトを得る部分は、はあくまでも理解(説明)のしやすさを優先させています。リアルの研究や投稿論文のSupplementなどで提供する場合は、直前で得たGCcontent
オブジェクトの情報を使うなどして一般化したコーディングを行いますし、行ってください。
#本番(expected)
hoge <- alphabetFrequency(fasta) #A,C,G,T,..の数を配列ごとにカウントした結果をhogeに格納
frequency <- colSums(hoge) #列ごとの総和をfrequencyに格納
GCcontent <- sum(frequency[2:3])/sum(frequency[1:4])#GC含量を計算(0.4101656)
expected <- c(rep(0.295*0.295, 4), rep(0.205*0.205, 4), rep(0.205*0.295, 8))#べた書きでnarabiの並びで期待値を算出
expected #確認してるだけです
## [1] 0.087025 0.087025 0.087025 0.087025 0.042025 0.042025 0.042025 0.042025
## [9] 0.060475 0.060475 0.060475 0.060475 0.060475 0.060475 0.060475 0.060475
以下は、表2.1の3列目の情報を得る部分のスクリプトです。まず、fasta
を入力としてdinucleotideFrequency
関数を実行し、配列ごとの2連続塩基の出現頻度をカウントした結果をhoge
に格納しています。次に、colSums
関数を用いてhoge
オブジェクトの列ごとの総和を計算しています。実行結果であるfrequency
オブジェクトはベクトルであり、1番目の要素がAAの数、2番目の要素がACの数、といった感じで格納されています。これは出現頻度情報なので、frequency/sum(frequency)
の計算をしてあげることで、出現確率情報に変換することができます。それがprobability
オブジェクトを得ている部分です。最後にnarabi
オブジェクトの並びにしたいので、probability[narabi]
を実行して順番を入れ替えています。
#本番(observed)
hoge <- dinucleotideFrequency(fasta, as.prob=F)#連続塩基の出現頻度情報をhogeに格納
frequency <- colSums(hoge) #列ごとの総和をfrequencyに格納
probability <- frequency/sum(frequency)#出現確率を計算した結果をprobabilityに格納
observed <- probability[narabi] #narabiの順番に変更
observed #確認してるだけです
## AA AT TA TT CC CG GC
## 0.08853346 0.07473471 0.04680258 0.08856020 0.04915571 0.05586645 0.06820623
## GG AC AG CA CT GA GT
## 0.04922880 0.05418324 0.05197784 0.07441033 0.05130263 0.05967948 0.05406350
## TC TG
## 0.05919212 0.07410273
以下は、表2.1a全体の情報を得るスクリプトです。シンプルに3つのベクトル(expected
,
observed
, and
observed/expected
)をcbind
関数を用いて列方向に結合(column
bind)しているだけです。
table2.1a <- cbind(expected, observed, observed/expected)
head(table2.1a) #最初の6行分を表示
## expected observed
## AA 0.087025 0.08853346 1.0173336
## AT 0.087025 0.07473471 0.8587729
## TA 0.087025 0.04680258 0.5378061
## TT 0.087025 0.08856020 1.0176409
## CC 0.042025 0.04915571 1.1696777
## CG 0.042025 0.05586645 1.3293622
ここではまず、転写開始点(TSS)上流1,000塩基の領域を調べたいので、その数値情報をparam_upstream
オブジェクトに与えています。次に、TxDb.Hsapiens.UCSC.hg19.knownGene(アノテーション情報のパッケージ)をロードして、パッケージ名と同じTxDb
という形式のオブジェクトをtxdb
という名前に変更(rename)しています。txdb
の表示結果の詳細を理解する必要はなく、「こんな感じに見えていたらアノテーション情報がtxdb
オブジェクトの中にちゃんと格納されているのだという程度でよい」です。
param_upstream <- 1000 #転写開始点上流の塩基配列数を指定
library(TxDb.Hsapiens.UCSC.hg19.knownGene)#パッケージのロード
## Error in library(TxDb.Hsapiens.UCSC.hg19.knownGene): 'TxDb.Hsapiens.UCSC.hg19.knownGene' という名前のパッケージはありません
txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene #renameしているだけです
## Error in eval(expr, envir, enclos): オブジェクト 'TxDb.Hsapiens.UCSC.hg19.knownGene' がありません
txdb #確認してるだけです
## Error in eval(expr, envir, enclos): オブジェクト 'txdb' がありません
以下は、転写開始点(TSS)上流1,000塩基の配列情報を得る部分のスクリプトです。まず、txdb
オブジェクトから遺伝子の座標情報を染色体の座標情報順で取得した結果をgn
オブジェクトに保存しています。次に、gn
オブジェクトを入力として、5’上流領域(5’
flanking
region)の座標情報を取得するためのflank
関数を実行することで、上流1,000塩基分の座標情報を取得しています。そして、上流1,000塩基分の範囲情報からなるhoge
オブジェクトを、getSeq
関数実行時のオプションとして与えています。fasta
実行結果の配列長(width
列)が全て1,000塩基であることから、なんとなくうまくとれてるっぽいことがわかります。
#本番
gn <- sort(genes(txdb)) #遺伝子の座標情報を取得
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'sort' に対するメソッドの選択時): 関数 "genes" を見つけることができませんでした
hoge <- flank(gn, width=param_upstream)#指定した範囲の座標情報を取得
## Error in h(simpleError(msg, call)): 引数 'x' の評価中にエラーが起きました (関数 'flank' に対するメソッドの選択時): オブジェクト 'gn' がありません
fasta <- getSeq(genome, hoge) #指定した範囲の塩基配列情報を取得
## Error in (function (classes, fdef, mtable) : 関数 'getSeq' (シグネチャ '"standardGeneric"' に対する) に対する継承メソッドを見付けることができません
fasta #確認してるだけです
## DNAStringSet object of length 75:
## width seq names
## [1] 362642 GAGGACGCGCACGTGGGCCGTG...CGGTGCTCGCGATATCTGAGTC ctg27_00064 dna:s...
## [2] 208498 AAAACCTGCACATAAAGGACCT...CTAATACCGCATAGATCCAAGA ctg15_00035 dna:s...
## [3] 157092 GTCAAAGGCTGCTGTTTGACCA...CTTGATGAAGCTGAACTGCCCG ctg40_00041 dna:s...
## [4] 145075 AGCTGATGAGCCAGCATTAATG...TATTCGCGTAGTTAGGTGGTCG ctg05_00082 dna:s...
## [5] 137019 TAGAAGCTACTGTATTGGACAG...AAGACCTGTTTTGCTTGGTGGT ctg49_00090 dna:s...
## ... ... ...
## [71] 2084 GAGACGAGGCGATTCGGATTGA...CTCGCGATATCTGAGTCGGAGA ctg68_00104 dna:s...
## [72] 2082 CCCCATTGAGGACGCGCACGTG...TGGTTGCGGCAATTCGTGATAC ctg22_00049 dna:s...
## [73] 1899 TGTTCCTTCTCCCTCGATCCAC...GCATCGTGGAGCTCAATTGAAT ctg62_00065 dna:s...
## [74] 1186 AATCAGTGGTTTTAACACTTTG...CCATCAGTCTTGCAAATCCCTT ctg72_00112 dna:s...
## [75] 981 AAGCTAATCTCTTAAAGCCATT...GAAGAGCCCAAACCGAGAAGCT ctg67_00088 dna:s...
以下は、表2.1bの1列目の情報を得る部分のスクリプトです。まず、fasta
を入力としてalphabetFrequency
関数を実行し、配列ごとのACGT各塩基の出現頻度をカウントした結果をhoge
に格納しています。hoge
自体は、298行×18列からなる数値行列です。1行目がchr1、2行目がchr2といった感じで、配列ごとの結果が各行に格納されています。各列にはA,
C, G, T,
…の並びで塩基ごとのカウント結果が格納されています。それゆえ、colSums
関数を用いて列ごとの総和を計算してやれば、つまりfasta
オブジェクト全体のAの数、Cの数、Gの数、Tの数の情報が得られます。実行結果であるfrequency
オブジェクトはベクトルであり、1番目の要素がAの数、2番目の要素がCの数、といった感じで格納されています。それゆえ、sum(frequency[2:3])/sum(frequency[1:4])
のような計算をしてあげれば、GC含量の情報(=
0.518723)が得られるのです。expected
オブジェクトを得る部分は、はあくまでも理解(説明)のしやすさを優先させています。リアルの研究や投稿論文のSupplementなどで提供する場合は、直前で得たGCcontent
オブジェクトの情報を使うなどして一般化したコーディングを行いますし、行ってください。
#本番(expected)
hoge <- alphabetFrequency(fasta) #A,C,G,T,..の数を配列ごとにカウントした結果をhogeに格納
frequency <- colSums(hoge) #列ごとの総和をfrequencyに格納
GCcontent <- sum(frequency[2:3])/sum(frequency[1:4]) #GC含量を計算(0.518723)
expected <- c(rep(0.24*0.24, 4), rep(0.26*0.26, 4), rep(0.26*0.24, 8))#べた書きでnarabiの並びで期待値を算出
expected #確認してるだけです
## [1] 0.0576 0.0576 0.0576 0.0576 0.0676 0.0676 0.0676 0.0676 0.0624 0.0624
## [11] 0.0624 0.0624 0.0624 0.0624 0.0624 0.0624
以下は、表2.1bの2列目の情報を得る部分のスクリプトです。まず、fasta
を入力としてdinucleotideFrequency
関数を実行し、配列ごとの2連続塩基の出現頻度をカウントした結果をhoge
に格納しています。次に、colSums
関数を用いてhoge
オブジェクトの列ごとの総和を計算しています。実行結果であるfrequency
オブジェクトはベクトルであり、1番目の要素がAAの数、2番目の要素がACの数、といった感じで格納されています。これは出現頻度情報なので、frequency/sum(frequency)
の計算をしてあげることで、出現確率情報に変換することができます。それがprobability
オブジェクトを得ている部分です。最後にnarabi
オブジェクトの並びにしたいので、probability[narabi]
を実行して順番を入れ替えています。
#本番(observed)
hoge <- dinucleotideFrequency(fasta, as.prob=F)#連続塩基の出現頻度情報をhogeに格納
frequency <- colSums(hoge) #列ごとの総和をfrequencyに格納
probability <- frequency / sum(frequency)#出現確率を計算した結果をprobabilityに格納
observed <- probability[narabi] #narabiの順番に変更
observed #確認してるだけです
## AA AT TA TT CC CG GC
## 0.08853346 0.07473471 0.04680258 0.08856020 0.04915571 0.05586645 0.06820623
## GG AC AG CA CT GA GT
## 0.04922880 0.05418324 0.05197784 0.07441033 0.05130263 0.05967948 0.05406350
## TC TG
## 0.05919212 0.07410273
以下は、表2.1b全体の情報を得るスクリプトです。シンプルに3つのベクトル(expected
,
observed
, and
observed/expected
)をcbind
関数を用いて列方向に結合(column
bind)しているだけです。
table2.1b <- cbind(expected, observed, observed/expected)
head(table2.1b) #最初の6行分を表示
## expected observed
## AA 0.0576 0.08853346 1.5370392
## AT 0.0576 0.07473471 1.2974777
## TA 0.0576 0.04680258 0.8125447
## TT 0.0576 0.08856020 1.5375035
## CC 0.0676 0.04915571 0.7271554
## CG 0.0676 0.05586645 0.8264267
R2.040とR2.050で得た2つのオブジェクト(table2.1a
とtable2.1b
)を、narabi
の情報を含めてファイル(table2.1.txt)に出力するスクリプトです。
####ファイルに保存
out_f <- "table2.1.txt" #出力ファイル名を指定してout_fに格納
tmp <- cbind(narabi, table2.1a, table2.1b)#保存したい情報をtmpに格納
write.table(tmp, out_f, sep="\t", append=F, quote=F, row.names=F)#tmpの中身を指定したファイル名で保存
例題2.2の内容も、表示させたい桁数を指定するやり方の提供を兼ねて、念のためここでも示しておきます。Saxonov論文のTable 1より、1 kb upstream resionsのGC含量は0.53、Observed CpG fractionは0.042であることがわかります。まずは「(1)このGC含量(0.53)を用いてCCの期待値を小数第4位まで示せ」を行います。
# CCの期待値
GCcontent <- 0.53 #GC含量
C <- GCcontent/2 #Cの期待値はGC含量の1/2
#結果の基本形
C*C #CCの期待値
## [1] 0.070225
#表示桁数を指定
param_digit <- 4 #表示させたい桁数
round(C*C, digits=param_digit) #小数点第(param_digit + 1)位で四捨五入した結果
## [1] 0.0702
次に、「(2) このGC含量(0.53)を用いてGAの期待値を小数第4位まで示せ」を行います。
GCcontent <- 0.53 #GC含量
G <- GCcontent/2 #Gの期待値はGC含量の1/2
A <- (1 - GCcontent)/2 #Aの期待値は(1 - GC含量)の1/2
#結果の基本形
G*A #GAの期待値
## [1] 0.062275
#表示桁数を指定
param_digit <- 4 #表示させたい桁数
round(G*A, digits=param_digit) #小数点第(param_digit + 1)位で四捨五入した結果
## [1] 0.0623
次に「(3) 上記1kb upstream regionsの情報(つまりGC含量は0.53、Observed CpG fractionは0.042)を用いてCGの観測値/期待値を少数第3位まで示せ」をやります。
param_digit <- 3 #表示させたい桁数
expected <- C*G #CGの期待値
observed <- 0.042 #問題文から与えられているCGの観測値
round(observed/expected, digits=param_digit)#小数点第(param_digit + 1)位で四捨五入した結果
## [1] 0.598
page057の8-9行目で述べている「…混同行列を内部的に作成し、それをもとに上記の感度や特異度などを算出して提示する…」をCRANから提供されているcaretというRパッケージを用いて実践します。caretは、機械学習や回帰系のRパッケージとして有名です。その原著論文(Khun M., J Stat Software, 2008)の引用回数は、7,000弱です(2023年9月18日調べ)。ここではまず、パッケージをインストールします。
BiocManager::install("caret", update=F)
以下は本番のコードです。まず、ヒトゲノム上のある範囲に計5つの領域が存在し、それぞれの領域はCpGアイランド(CGI)またはそれ以外(non-CGI)のいずれかのラベルが付与されていると仮定します(これが真実の情報)。この範囲に存在する計5つの領域の塩基配列情報をそれぞれ与えて、CGIかどうかを判定させた結果が手元にあったとします(これが予測の結果)。この要素数が同じ2つのベクトル(truthdayo
とpredicted
)を入力としてcaretパッケージが提供するconfusionMatrix
関数を実行すると、正確度(Accuracy)や感度(Sensitivity)などの結果が得られます。
truthdayo <- c("CGI", "non-CGI", "CGI", "CGI", "non-CGI")#真実の情報
predicted <- c("CGI", "CGI", "CGI", "CGI", "CGI") #予測の結果
library(caret) #パッケージのロード
confusionMatrix(data = factor(predicted), #予測の結果はdataのところ
reference = factor(truthdayo),#真実の情報はreferenceのところ
positive = "CGI") #Positiveを定義
## Confusion Matrix and Statistics
##
## Reference
## Prediction CGI non-CGI
## CGI 3 2
## non-CGI 0 0
##
## Accuracy : 0.6
## 95% CI : (0.1466, 0.9473)
## No Information Rate : 0.6
## P-Value [Acc > NIR] : 0.6826
##
## Kappa : 0
##
## Mcnemar's Test P-Value : 0.4795
##
## Sensitivity : 1.0
## Specificity : 0.0
## Pos Pred Value : 0.6
## Neg Pred Value : NaN
## Prevalence : 0.6
## Detection Rate : 0.6
## Detection Prevalence : 1.0
## Balanced Accuracy : 0.5
##
## 'Positive' Class : CGI
##
以下は、よりシンプルに書いたスクリプトです。文字列ベクトルではなく、0
or
1の数値ベクトルを入力として与えています。confusionMatrix
関数は”CGI”
or
“non-CGI”のラベル情報をアルファベット順にソートするため、対応するラベルを”0”
or
“1”にしてpositive = "0"
をオプションとして与えることで、得られる混同行列の左右の列を意図通りに並べています。
truthdayo <- c(0, 1, 0, 0, 1) #真実の情報
predicted <- c(0, 0, 0, 0, 0) #予測の結果
library(caret) #パッケージのロード
confusionMatrix(data = factor(predicted), #予測の結果はdataのところ
reference = factor(truthdayo),#真実の情報はreferenceのところ
positive = "0") #Positiveを定義
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 3 2
## 1 0 0
##
## Accuracy : 0.6
## 95% CI : (0.1466, 0.9473)
## No Information Rate : 0.6
## P-Value [Acc > NIR] : 0.6826
##
## Kappa : 0
##
## Mcnemar's Test P-Value : 0.4795
##
## Sensitivity : 1.0
## Specificity : 0.0
## Pos Pred Value : 0.6
## Neg Pred Value : NaN
## Prevalence : 0.6
## Detection Rate : 0.6
## Detection Prevalence : 1.0
## Balanced Accuracy : 0.5
##
## 'Positive' Class : 0
##
以下は、感度を下げて特異度を上げるべく、予測結果を変えたスクリプトです。
truthdayo <- c(0, 1, 0, 0, 1) #真実の情報
predicted <- c(1, 1, 1, 0, 1) #予測の結果
library(caret) #パッケージのロード
confusionMatrix(data = factor(predicted), #予測の結果はdataのところ
reference = factor(truthdayo),#真実の情報はreferenceのところ
positive = "0") #Positiveを定義
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 1 0
## 1 2 2
##
## Accuracy : 0.6
## 95% CI : (0.1466, 0.9473)
## No Information Rate : 0.6
## P-Value [Acc > NIR] : 0.6826
##
## Kappa : 0.2857
##
## Mcnemar's Test P-Value : 0.4795
##
## Sensitivity : 0.3333
## Specificity : 1.0000
## Pos Pred Value : 1.0000
## Neg Pred Value : 0.5000
## Prevalence : 0.6000
## Detection Rate : 0.2000
## Detection Prevalence : 0.2000
## Balanced Accuracy : 0.6667
##
## 'Positive' Class : 0
##