В этом разделе мы рассмотрим основные подходы в
аннотации сплайсинговых событий, идентифицированных с помощью элайнера Subjunc. В качестве примера мы
возьмем BED файл, использованный нами ранее, и загрузим его в рабочее пространство R среды с помощью функции import, как это
было описано в разделе “Загрузка файла формата BED в рабочее пространство R среды”.
library(rtracklayer)
splEvents = import(con = "D:/Transcriptome/SRR1145838.junction.bed",
format = "bed",
trackLine = FALSE,
genome = "hg38",
colnames = NULL,
which = NULL,
seqinfo = NULL)
После загрузки данных в созданном объекте splEvents мы преобразуем слот ranges – заменим геномные координаты блоков на координаты собственно сплайсинговых событий (так, что бы левая координата start соответствовала последнему нуклеотиду предшествующего экзона, а правая координата end – первому нуклеотиду следующего экзона). Кроме того, в преобразованном объекте мы оставим только два столбца метаданных – name и score, - так как остальные столбцы нам не понадобятся.
ranges(splEvents)
= IRanges(start =
ranges(splEvents)@start + width(unlist(splEvents$blocks)[c(TRUE, FALSE)]) - 1,
end = end(splEvents)
- width(unlist(splEvents$blocks)[c(TRUE, FALSE)]) + 1)
splEvents = splEvents[, 1:2]
splEvents
GRanges object
with 245354 ranges and 2 metadata columns:
seqnames
|
ranges
|
strand
|
|
|
name
|
score
|
||
<Rle>
|
<IRanges>
|
<Rle>
|
|
|
<character>
|
<numeric>
|
||
[1]
|
chr1
|
[15038,
|
15796]
|
-
|
|
|
JUNC00202937
|
15
|
[2]
|
chr1
|
[15038,
|
186317]
|
-
|
|
|
JUNC00167075
|
30
|
[3]
|
chr1
|
[16310,
|
16607]
|
-
|
|
|
JUNC00140845
|
1
|
[4]
|
chr1
|
[16765,
|
16858]
|
-
|
|
|
JUNC00100248
|
13
|
[5]
|
chr1
|
[17055,
|
17233]
|
-
|
|
|
JUNC00214170
|
6
|
-------
seqinfo: 455
sequences from hg38 genome
Генная
принадлежность идентифицированных сплайсинговых событий.
Теперь мы можем приступить к аннотации сплайсинговых событий. На первом
этапе мы определим генную принадлежность сплайсинговых событий. Для этого в
рабочее пространство R среды необходимо загрузить координаты
известных генов (а точнее единиц транскрипции, без внешних промоторных регионов)
человека, взятые из автоматической системы аннотирования Ensembl (81-й выпуск аннотаций, основанный на референс-сборке GRCh38.p3
генома человека, июнь 2015).
Мы воспользуемся заранее подготовленным текстовым файлом, содержащим пять
полей, разделенных табуляцией: идентификационный номер гена по Ensembl (Ensembl_Gene_ID), название хромосомы (Chromosome), начало (Start) и конец (End) гена в хромосоме, а также цепь (Strand), - и после загрузки данных преобразуем их в объект класса GRanges.
ensGenes = read.table("D:/Transcriptome/Ensembl genes,
genomic coordinates, GRCh38.p3 human release 81.txt",
sep = "\t",
header
= TRUE,
quote = "\"",
as.is
= TRUE)
ensGenes =
makeGRangesFromDataFrame(ensGenes, keep.extra.columns = TRUE)
ensGenes
GRanges object
with 60411 ranges and 1 metadata column:
seqnames
|
ranges
|
strand
|
|
|
Ensembl_Gene_ID
|
||
<Rle>
|
<IRanges>
|
<Rle>
|
|
|
<character>
|
||
[1]
|
chrX
|
[100627109,
|
100639991]
|
-
|
|
|
ENSG00000000003
|
[2]
|
chrX
|
[100584802,
|
100599885]
|
+
|
|
|
ENSG00000000005
|
[3]
|
chr20
|
[50934867,
|
50958555]
|
-
|
|
|
ENSG00000000419
|
[4]
|
chr1
|
[169849631,
|
169894267]
|
-
|
|
|
ENSG00000000457
|
[5]
|
chr1
|
[169662007,
|
169854080]
|
+
|
|
|
ENSG00000000460
|
-------
seqinfo: 24 sequences from an unspecified genome; no seqlengths
seqinfo: 24 sequences from an unspecified genome; no seqlengths
Теперь можно сопоставить геномные интервалы в двух объектах. Для этого мы
воспользуемся функцией findOverlaps из R/Bioconductor библиотеки
IRanges (саму библиотеку дополнительно загружать не надо, так
как она загружается в рабочее пространство R среды вместе
с библиотекой rtracklayer). Эта функция имеет семь аргументов:
q query – объект класса GRanges, содержащий список
интервалов, которые необходимо картировать. В нашем случае это объект splEvents. В
целом, на этот аргумент может быть подан любой другой объект близкого класса: Ranges, Views, RangesList, ViewsList или RangedData;
q subject – объект класса GRanges, содержащий список
интервалов, по которым будет идти картирование интервалов из query. В нашем случае это
объект ensGenes. На
этот аргумент может быть подан любой другой объект, но того же класса, что и
объект, присвоенный аргументу query;
q maxgap – максимальное
расстояние, на котором могут находиться два интервала, что бы считаться перекрывающимися.
Значение этого аргумента может быть только целочисленным положительным;
q minoverlap – минимально необходимое
перекрытие для двух интервалов, что бы классифицировать их как перекрывающиеся.
Значение этого аргумента может быть только целочисленным положительным;
q type – тип перекрытия.
Этот аргумент может принимать одно из следующих значений: “any”
(значение является значением по умолчанию и допускает любой вариант перекрытия),
“start” (два интервала считаются перекрывающимися, если полностью
совпадают их начала), “end” (два интервала считаются
перекрывающимися, если полностью совпадают их концы), “within”
(интервал из query должен полностью уместиться
в интервал из subject) и “equal”
(два интервала должны полностью совпасть);
q select – метод выбора
перекрывающегося интервала, если интервал из query перекрывается с несколькими интервалами
из subject. Этот
аргумент может принимать одно из следующих значений: “all”
(значение является значением по умолчанию и возвращает все обнаруженные
перекрытия), “first” (возвращает первый интервал из всего списка перекрывающихся
интервалов), “last” (возвращает последний интервал из всего списка перекрывающихся
интервалов) и “arbitrary” (возвращает
произвольно выбранный интервал из всего списка перекрывающихся интервалов);
q ignore.strand – логический аргумент, определяющий, будет ли учитываться
цепь при поиске перекрытий (FALSE),
или же принадлежность интервалов к той или иной цепи будет игнорироваться (TRUE).
Аргумент добавлен к функции findOverlaps в R/Bioconductor библиотеке GenomicRanges, но отсутствует в библиотеке IRanges.
hits = findOverlaps(query =
splEvents,
subject = ensGenes,
maxgap = 0L,
minoverlap = 1L,
type = "within",
select = "all",
ignore.strand = FALSE)
hits
Hits object with
229669 hits and 0 metadata columns:
queryHits
|
subjectHits
|
|
<integer>
|
<integer>
|
|
[1]
|
1
|
28054
|
[2]
|
3
|
28054
|
[3]
|
4
|
28054
|
[4]
|
5
|
28054
|
[5]
|
6
|
28054
|
...
|
...
|
...
|
[229665]
|
245311
|
15278
|
[229666]
|
245312
|
15278
|
[229667]
|
245313
|
15278
|
[229668]
|
245314
|
15278
|
[229669]
|
245343
|
35434
|
-------
queryLength: 245354
subjectLength: 60411
subjectLength: 60411
Полученный объект hits принадлежит
к специальному классу объектов Hits, реализованному в R/Bioconductor библиотеке
S4Vectors.
Объекты такого класса хранят информацию о пересечениях (hits) двух векторов, один из которых называется запросом (query), а второй – предметом запроса (subject). В нашем объекте hits в столбце
queryHits стоят номера
строк (индексы) из объекта splEvents, а в столбце subjectHits номера строк из объекта ensGenes, с которыми строки из объекта splEvents перекрываются.
Следует отметить, что не все сплайсинговые события перекрылись с аннотированными в Ensembl генами: запрос length(unique(queryHits(hits))) дает цифру 217944, в то время как исходные данные включают 245354 записи. Кроме того, часть сплайсинговых событий может быть приписана не к одному, а к нескольким генам, что обусловлено перекрытием самих генов. В связи с этим мы сделаем две вещи: во-первых, создадим упорядоченный список events только тех сплайсинговых событий, которые перекрываются с известными генами, причем вместе с названиями этих генов; во-вторых, упростим объект splEvents, удалив из него те сплайсинговые события, которые не перекрываются с известными генами, отсортируем этот объект по полю name и добавим, воспользовавшись списком events, новое поле gene_ID.
При необходимости полученные результаты могут быть сохранены в виде, например, текстового файла, содержащего стандартную таблицу с табуляцией:
Теперь мы можем выяснить, насколько сильны интересующие нас сайты сплайсинга. Сделать это можно в рамках одной или нескольких математических моделей, связывающих нуклеотидную последовательность сайта сплайсинга и его силу: модель максимальной энтропии (maximum entropy model), модель максимально зависимой декомпозиции (maximum dependence decomposition model), марковская модель первой степени (first-order Markov model) и взвешенная модель (weight matrix model). Об этих моделях можно подробнее почитать, например, в работе Yeo G. и Burge C. B. "Maximum entropy modeling of short sequence motifs with applications to RNA splicing signals”, опубликованной в 2004 году в 11-м томе журнала Journal of Computational Biology.
Следует отметить, что не все сплайсинговые события перекрылись с аннотированными в Ensembl генами: запрос length(unique(queryHits(hits))) дает цифру 217944, в то время как исходные данные включают 245354 записи. Кроме того, часть сплайсинговых событий может быть приписана не к одному, а к нескольким генам, что обусловлено перекрытием самих генов. В связи с этим мы сделаем две вещи: во-первых, создадим упорядоченный список events только тех сплайсинговых событий, которые перекрываются с известными генами, причем вместе с названиями этих генов; во-вторых, упростим объект splEvents, удалив из него те сплайсинговые события, которые не перекрываются с известными генами, отсортируем этот объект по полю name и добавим, воспользовавшись списком events, новое поле gene_ID.
events = data.frame(cbind(splEvents[queryHits(hits), ]$name,
ensGenes[subjectHits(hits), ]$Ensembl_Gene_ID),
stringsAsFactors = FALSE)
events = aggregate(events$X2 ~ events$X1, paste, collapse = ",", data = events)
colnames(events) = c("junction", "gene_ID")
splEvents = splEvents[unique(queryHits(hits)), ]
splEvents = splEvents[order(splEvents$name), ]
splEvents$gene_ID = events$gene_ID
splEvents = sort(splEvents)
splEvents
GRanges object
with 217944 ranges and 3 metadata columns:
seqnames
|
ranges
|
strand
|
|
|
name
|
score
|
gene_ID
|
||
<Rle>
|
<IRanges>
|
<Rle>
|
|
|
<character>
|
<numeric>
|
<character>
|
||
[1]
|
chr1
|
[629963,
|
630048]
|
+
|
|
|
JUNC00197520
|
65
|
ENSG00000225630
|
[2]
|
chr1
|
[634018,
|
634319]
|
+
|
|
|
JUNC00241998
|
1
|
ENSG00000248527
|
[3]
|
chr1
|
[634550,
|
634610]
|
+
|
|
|
JUNC00102726
|
14
|
ENSG00000198744
|
[4]
|
chr1
|
[827775,
|
829003]
|
+
|
|
|
JUNC00075428
|
110
|
ENSG00000228794
|
[5]
|
chr1
|
[95151419,
|
95173816]
|
+
|
|
|
JUNC00245349
|
1
|
ENSG00000152078, ENSG00000271092
|
-------
seqinfo: 455
sequences from hg38 genome
При необходимости полученные результаты могут быть сохранены в виде,
например, обычного текстового файла со столбцами, разделенными табуляцией:
res = as.data.frame(splEvents)
write.table(res,
file = "D:/Transcriptome/Splicing events vs genes.txt",
sep = "\t",
quote = FALSE,
col.names = TRUE,
row.names = FALSE)
Идентифицированные сплайсинговые события vs известные
сплайсинговые события.
Теперь мы выясним, какая часть из идентифицированных с помощью элайнера Subjunc сплайсинговых событий содержит уже описанные ранее
стыки экзонов, а какая включает что-то новое, ранее не описанное. Что бы
реализовать задумку мы воспользуемся транскрипционными моделями генов человека,
построенными автоматической системой аннотирования Ensembl (81-й выпуск аннотаций, основанный на референс-сборке GRCh38.p3
генома человека, июнь 2015), и извлечем из них уже
известные варианты стыков экзонов. Конечно, данные, обобщенные в Ensembl, не являются всеобъемлющими, но для наших целей вполне
подходят.
Для этого нам понадобятся функциональные возможности двух дополнительных R/Bioconductor библиотек
– GenomicFeatures и SGSeq.
Возможности первой библиотеки предоставят нам доступ к локальной базе SQLite, содержащей транскрипционные модели генов человека
(более подробно об этом написано в разделе “Организация и создание объектовкласса TxDb”). Возможности
же библиотеки SGSeq позволят нам извлечь из транскрипционных моделей
только экзонные стыки, причем полученные данные о стыках будут организованы в
точно такой же объект класса GRanges, как и наш объект splEvents. Консолидированный R код представлен ниже.
library(GenomicFeatures)
library(SGSeq)
TxDb = loadDb("D:/Transcriptome/Ensembl.GRCh38.p3.release81.sqlite")
TxFe =
convertToTxFeatures(TxDb)
refSpl = TxFe[TxFe@type == "J", ]
refSpl = as.data.frame(refSpl)
refSpl$seqnames = paste("chr", refSpl$seqnames, sep = "")
chr = c(paste("chr", c(1:22), sep = ""), "chrX", "chrY")
refSpl =
refSpl[refSpl$seqnames %in% chr,
][, -6:-8]
rownames(refSpl) = NULL
refSpl = refSpl[!duplicated(refSpl), ]
refSpl =
makeGRangesFromDataFrame(refSpl, keep.extra.columns = TRUE)
refSpl
GRanges object
with 347559 ranges and 0 metadata columns:
seqnames
|
ranges
|
strand
|
||
<Rle>
|
<IRanges>
|
<Rle>
|
||
[1]
|
сhr1
|
[12057,
|
12179]
|
+
|
[2]
|
сhr1
|
[12057,
|
12613]
|
+
|
[3]
|
сhr1
|
[12697,
|
12975]
|
+
|
[4]
|
chr1
|
[12721,
|
13221]
|
+
|
[5]
|
chr1
|
[13052,
|
13221]
|
+
|
-------
seqinfo: 24
sequences from an unspecified genome; no seqlengths
Теперь мы можем сравнить два объекта – splEvents и refSpl, - и выяснить насколько полно они перекрываются. Для этого мы
воспользуемся все той же функцией findOverlaps,
но поменяем значение аргумента type на “equal” (равный).
hits = findOverlaps(query =
splEvents,
subject = refSpl,
maxgap = 0L,
minoverlap = 1L,
type = "equal",
select = "all",
ignore.strand = FALSE)
hits
Hits object with
144931 hits and 0 metadata columns:
queryHits
|
subjectHits
|
|
<integer>
|
<integer>
|
|
[1]
|
4
|
46
|
[2]
|
6
|
48
|
[3]
|
7
|
49
|
[4]
|
8
|
50
|
[5]
|
13
|
55
|
...
|
...
|
...
|
[144927]
|
217934
|
345767
|
[144928]
|
217935
|
345768
|
[144929]
|
217938
|
345769
|
[144930]
|
217943
|
345771
|
[144931]
|
217944
|
347553
|
-------
queryLength: 217944
subjectLength: 347559
Видно, что из 217944 сплайсинговых событий, содержащихся в объекте splEvents, 144931 событие может быть классифицировано как уже
известное, а остальные являются новыми. В действительности же, как это будет показано
далее, большинство из идентифицированных “новых” событий подтверждается небольшим
количеством ридов и, скорее всего, является шумом.
В завершение мы добавим к объекту splEvents новый столбец status, где будет содержаться
информация о статусе идентифицированных сплайсинговых событий – являются ли они
уже известными или же новыми.
splEvents$status = "known"
splEvents[-queryHits(hits),
]$status = "new"
При необходимости модифицированный объект splEvents может быть сохранен в виде обычного текстового файла, как
это уже описывалось выше.
Количественная характеристика идентифицированных
сплайсинговых событий.
Рассмотрим несколько вариантов количественной характеристики
идентифицированных сплайсинговых событий. Первой из них будет дистанция сплайсинга
(splicing distance) – фактически размер интрона, который удаляется во время объединения
экзонов. Консолидированный код для решения этой задачи приведен ниже, а
результат отображен на рисунке 1. На рисунке 1 отчетливо видны два пика – минорный пик
так называемых минимальных интронов (с размером между 50 и 150 нуклеотидами) и
основной пик стандартных интронов длиной более 150 нуклеотидов.
empSplDistance = log(width(splEvents) - 1, 10)
refSplDistance = log(width(refSpl) - 1, 10)
par(omi = c(0, 0.1, 0, 0), mai
= c(1, 1, 0.1, 0.1), lwd
= 3)
plot(density(empSplDistance),
col = "red", ann = FALSE, cex.axis = 2, xlim = c(0, 8), ylim = c(0, 0.6))
lines(density(refSplDistance),
col = "blue")
title(ylab = "Density", xlab = "Splicing
distance, log10(nucleotides)", cex.lab = 2.5)
legend(x =
"topright", legend = c("experimental
events", "Ensembl"), col = c("red",
"blue"), lwd = 3, bty = "n", cex = 2)Рисунок 1. Распределение дистанций сплайсинга среди экспериментально идентифицированных и аннотированных в Ensembl сплайсинговых событий. |
При необходимости полученные результаты могут быть сохранены в виде, например, текстового файла, содержащего стандартную таблицу с табуляцией:
res = cbind(density(empSplDistance)$x,
density(empSplDistance)$y,
density(refSplDistance)$x, density(refSplDistance)$y)
colnames(res) = c("Experimental events",
"Density", "Ensembl events", "Density")
write.table(res, file = "Splicing distances.txt", sep =
"\t", quote = FALSE, col.names = TRUE, row.names = FALSE)
Второй характеристикой будет количество ридов, подтверждающих сплайсинговое
событие. В англоязычной литературе для обозначения этого параметра используется
несколько терминов: number of supporting reads, sequencing depth или coverage. В нашем объекте splEvents такого рода информация содержится в поле score, так что нам остается только извлечь ее и привести в
надлежащий вид.
library(edgeR)
splEvents$cpm = log(cpm(splEvents$score), 2)
par(omi = c(0, 0.05, 0, 0), mai
= c(1, 1, 0.1, 0.1), lwd
= 3)
plot(density(splEvents$cpm),
col = "red", ann = FALSE, cex.axis = 2, xlim = c(-5, 10), ylim = c(0, 1.2))
lines(density(splEvents[splEvents$status
== "new", ]$cpm), col =
"blue")
lines(density(splEvents[splEvents$status
== "known", ]$cpm), col =
"darkgreen")
abline(v = 0, col = "black", lty = 2)
title(ylab = "Density", xlab =
"Sequencing depth, log2(CPM)", cex.lab = 2.5)
legend(x = "topright", legend = c("all
events", "new events", "known events"),
col = c("red",
"blue", "darkgreen"), lwd = 3, bty = "n", cex = 2)
Код, представленный выше, включает CPM-нормализацию и log2-трансформацию первичных данных. Под CPM-нормализацией (counts per million) подразумевается пересчет количества ридов,
подтверждающих сплайсинговые события, на 1 млн. ридов, содержащихся в RNA-Seq библиотеке. Для проведения такого
рода нормализации мы воспользовались готовой функцией cpm из R/Bioconductor библиотеки
edgeR.
На обобщающем рисунке 2 видно, что многие сплайсинговые события подтверждаются
лишь небольшим количеством ридов. Особенно это заметно для “новых” событий, так
что если выставить порог в 1 рид на миллион (пунктирная линия), то из этой
группы событий сохранится лишь незначительная часть.Рисунок 2. Подтвержденность ридами идентифицированных сплайсинговых событий. |
Оценка силы сайтов сплайсинга.
Что бы оценить силу сайтов, задействованных в сплайсинге (score of splice sites, strength of splice sites), нам необходимо получить их сиквенс. Для этого нам понадобятся
функциональные возможности трех R/Bioconductor библиотек:
GenomicRanges (для создания объектов класса GRanges), Biostrings (необходима для извлечения сиквенсов и их записи в формате FASTA) и BSgenome.Hsapiens.UCSC.hg38 (как источник последовательности референс-сборки GRCh38
генома человека). Первые две
уже загружены в рабочее пространство R среды, так как они связаны с
библиотекой rtracklayer, а третью мы загрузим дополнительно. Далее
последовательно будут созданы объекты fiveSS и threeSS с координатами 5’ и 3’ сайтов сплайсинга, из
референс-сборки GRCh38 генома человека по полученным координатам будут
извлечены сиквенсы этих сайтов сплайсинга и сохранены в виде отдельных файлов в
FASTA формате.
Консолидированный код, а также фрагмент одного из итоговых объектов, приведены
ниже. Этот код, конечно, не претендует быть самым эффективным и универсальным,
но может рассматриваться как один из вариантов решения поставленной задачи.
library(BSgenome.Hsapiens.UCSC.hg38)
splEvents_Plus =
splEvents[splEvents@strand == "+", ]
splEvents_Minus =
splEvents[splEvents@strand == "-", ]
fiveSS_Plus =
as.data.frame(splEvents_Plus)
fiveSS_Plus$start = fiveSS_Plus$start - 2
fiveSS_Plus$end = fiveSS_Plus$start + 8
fiveSS_Minus =
as.data.frame(splEvents_Minus)
fiveSS_Minus$end = fiveSS_Minus$end + 2
fiveSS_Minus$start = fiveSS_Minus$end - 8
fiveSS = c(makeGRangesFromDataFrame(fiveSS_Plus,
keep.extra.columns = TRUE),
makeGRangesFromDataFrame(fiveSS_Minus,
keep.extra.columns = TRUE))
fiveSS_Seq = getSeq(Hsapiens,
fiveSS)
names(fiveSS_Seq) = fiveSS$name
fiveSS_Seq = fiveSS_Seq[order(names(fiveSS_Seq)),
]
writeXStringSet(x
= fiveSS_Seq, filepath = "Splicing events, 5' splice sites,
FASTA.fasta", format = "fasta", width = 50)
threeSS_Plus =
as.data.frame(splEvents_Plus)
threeSS_Plus$start = threeSS_Plus$end - 20
threeSS_Plus$end = threeSS_Plus$end + 2
threeSS_Minus =
as.data.frame(splEvents_Minus)
threeSS_Minus$start = threeSS_Minus$start - 2
threeSS_Minus$end = threeSS_Minus$start + 22
threeSS = c(makeGRangesFromDataFrame(threeSS_Plus,
keep.extra.columns = TRUE),
makeGRangesFromDataFrame(threeSS_Minus,
keep.extra.columns = TRUE))
threeSS_Seq = getSeq(Hsapiens,
threeSS)
names(threeSS_Seq) = threeSS$name
threeSS_Seq = threeSS_Seq[order(names(threeSS_Seq)),
]
writeXStringSet(x
= threeSS_Seq, filepath = "Splicing events, 3' splice sites,
FASTA.fasta", format = "fasta", width = 50)
head(fiveSS_Seq)
A DNAStringSet instance of length 6
|
width
|
seq
|
names
|
[1]
|
9
|
GTGGTGGGT
|
JUNC00000001
|
[2]
|
9
|
GAGGTATGT
|
JUNC00000002
|
[3]
|
9
|
AGGGTCAGT
|
JUNC00000003
|
[4]
|
9
|
CTGGTGAGT
|
JUNC00000004
|
[5]
|
9
|
AAGGTAAGG
|
JUNC00000005
|
[6]
|
9
|
AAGGTATCA
|
JUNC00000006
|
Теперь мы можем выяснить, насколько сильны интересующие нас сайты сплайсинга. Сделать это можно в рамках одной или нескольких математических моделей, связывающих нуклеотидную последовательность сайта сплайсинга и его силу: модель максимальной энтропии (maximum entropy model), модель максимально зависимой декомпозиции (maximum dependence decomposition model), марковская модель первой степени (first-order Markov model) и взвешенная модель (weight matrix model). Об этих моделях можно подробнее почитать, например, в работе Yeo G. и Burge C. B. "Maximum entropy modeling of short sequence motifs with applications to RNA splicing signals”, опубликованной в 2004 году в 11-м томе журнала Journal of Computational Biology.
Мы применим только первую из указанных моделей. Что бы не создавать ее заново,
мы воспользуемся возможностями R/Bioconductor библиотеки
spliceSites, разработанной профессором Wolfgang Kaisers из Дюссельдорфского университета
им. Генриха Гейне.
source("https://bioconductor.org/biocLite.R")
biocLite("spliceSites")
library(spliceSites)
maxEnt = load.maxEnt()
Далее модель максимальной энтропии maxEnt будет последовательно подгоняться
под наши эмпирические данные и будет рассчитываться интересующий нас параметр
этой модели – сила сайтов сплайсинга. Для этого мы используем две функции из библиотеки
spliceSites – score5 и score3, - работающие с 5’ и 3’ сайтами сплайсинга, соответственно. Эти функции
имеют три одинаковых аргумента:
q x – модель;
q seq – нуклеотидная последовательность
сайта сплайсинга;
q pos – позиция в
нуклеотидной последовательности, для которой будет вестись расчет.
Ниже представлен консолидированный код. На больших объемах данных этот код
работает довольно медленно и требует оптимизации, но для нашего примера вполне
подходит.
scores = matrix(ncol = 2, nrow = length(splEvents))
for (i in 1:length(splEvents)){
scores[i, 1] = round(score5(x = maxEnt, seq = toString(fiveSS_Seq[i]), pos = 3), digits = 2)
scores[i, 2] = round(score3(x = maxEnt, seq = toString(threeSS_Seq[i]), pos = 20), digits = 2)
if(i%%100 == 0){
cat("Junction",
i, "of the", length(splEvents),
"has been processed...\n")
flush.console()
}
}
scores = data.frame(cbind(names(fiveSS_Seq),
scores))
colnames(scores) = c("name", "fiveSS",
"threeSS")
head(scores)
|
name
|
fiveSS
|
threeSS
|
1
|
JUNC00000001
|
4.29
|
10.7
|
2
|
JUNC00000002
|
9.81
|
5.4
|
3
|
JUNC00000003
|
5.85
|
6.53
|
4
|
JUNC00000004
|
10.1
|
7.23
|
5
|
JUNC00000005
|
10.51
|
9.18
|
6
|
JUNC00000006
|
7.22
|
6.92
|
Полученные результаты мы можем добавить к объекту splEvents и, например, сохранить в виде обычного текстового
файла со столбцами, разделенными табуляцией:
splEvents = splEvents[order(splEvents$name), ]
splEvents$fiveSS = as.numeric(levels(scores$fiveSS)[scores$fiveSS])
splEvents$threeSS =
as.numeric(levels(scores$threeSS)[scores$threeSS])
res = as.data.frame(splEvents)
write.table(res,
file = "D:/Transcriptome/Splicing
events, strength of splice sites.txt",
sep
= "\t",
quote = FALSE,
col.names = TRUE,
row.names = FALSE)
Поскольку эти результаты являются обычными числовыми векторами, то они
могут быть подвергнуты любым вариантам анализа, релевантным тем задачам, которые
стоят перед исследованием. При наличии инициативы и пожеланий со стороны
читателей блога мы можем более подробно рассмотреть дополнительные аналитические
подходы в работе с полученными данными. Мы можем также обсудить дополнительные подходы
в аннотировании сплайсинговых событий, так как рассмотренные подходы являются
лишь верхушкой айсберга возможностей.
Комментариев нет:
Отправить комментарий