Это немного похоже на этот вопрос о подсчете вхождений строк, но мне нужно решение, которое работает с dplyr и способно применять тесты на основе результатов.
В геномике естьидея k-мер, которая является каждой подстрокой длины k внутри более длинной строки.Мне нужно взять несколько строк (геномных последовательностей) и найти (потенциально перекрывающиеся) k-мер длины 5, которые встречаются внутри строки ровно 4 раза.
Я могу подсчитать количество вхождений каждого k-мер с помощью следующего:
sequence1 <- "CGGACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAA"
sequence2 <- "GGACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAAT"
sequence3 <- "GACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAATG"
sequences <- list(sequence1, sequence2, sequence3)
#Generate all k-mers of length 5 within each sequence
k <- 5
kmers <- map(sequences, function(x) {
map_chr(seq_len(nchar(x) - k + 1), function(y) str_sub(x, y, y + k - 1))}) %>%
set_names(sequences)
kmers
Дает k-мер:
#> $CGGACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAA
#> [1] "CGGAC" "GGACT" "GACTC" "ACTCG" "CTCGA" "TCGAC" "CGACA" "GACAG"
#> [9] "ACAGA" "CAGAT" "AGATG" "GATGT" "ATGTG" "TGTGA" "GTGAA" "TGAAG"
#> [17] "GAAGA" "AAGAA" "AGAAA" "GAAAT" "AAATG" "AATGT" "ATGTG" "TGTGA"
#> [25] "GTGAA" "TGAAG" "GAAGA" "AAGAC" "AGACT" "GACTG" "ACTGA" "CTGAG"
#> [33] "TGAGT" "GAGTG" "AGTGA" "GTGAA" "TGAAG" "GAAGA" "AAGAG" "AGAGA"
#> [41] "GAGAA" "AGAAG" "GAAGA" "AAGAG" "AGAGG" "GAGGA" "AGGAA" "GGAAA"
#> [49] "GAAAC" "AAACA" "AACAC" "ACACG" "CACGA" "ACGAC" "CGACA" "GACAC"
#> [57] "ACACG" "CACGA" "ACGAC" "CGACA" "GACAT" "ACATT" "CATTG" "ATTGC"
#> [65] "TTGCG" "TGCGA" "GCGAC" "CGACA" "GACAT" "ACATA" "CATAA"
#>
#> $GGACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAAT
#> [1] "GGACT" "GACTC" "ACTCG" "CTCGA" "TCGAC" "CGACA" "GACAG" "ACAGA"
#> [9] "CAGAT" "AGATG" "GATGT" "ATGTG" "TGTGA" "GTGAA" "TGAAG" "GAAGA"
#> [17] "AAGAA" "AGAAA" "GAAAT" "AAATG" "AATGT" "ATGTG" "TGTGA" "GTGAA"
#> [25] "TGAAG" "GAAGA" "AAGAC" "AGACT" "GACTG" "ACTGA" "CTGAG" "TGAGT"
#> [33] "GAGTG" "AGTGA" "GTGAA" "TGAAG" "GAAGA" "AAGAG" "AGAGA" "GAGAA"
#> [41] "AGAAG" "GAAGA" "AAGAG" "AGAGG" "GAGGA" "AGGAA" "GGAAA" "GAAAC"
#> [49] "AAACA" "AACAC" "ACACG" "CACGA" "ACGAC" "CGACA" "GACAC" "ACACG"
#> [57] "CACGA" "ACGAC" "CGACA" "GACAT" "ACATT" "CATTG" "ATTGC" "TTGCG"
#> [65] "TGCGA" "GCGAC" "CGACA" "GACAT" "ACATA" "CATAA" "ATAAT"
#>
#> $GACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAATG
#> [1] "GACTC" "ACTCG" "CTCGA" "TCGAC" "CGACA" "GACAG" "ACAGA" "CAGAT"
#> [9] "AGATG" "GATGT" "ATGTG" "TGTGA" "GTGAA" "TGAAG" "GAAGA" "AAGAA"
#> [17] "AGAAA" "GAAAT" "AAATG" "AATGT" "ATGTG" "TGTGA" "GTGAA" "TGAAG"
#> [25] "GAAGA" "AAGAC" "AGACT" "GACTG" "ACTGA" "CTGAG" "TGAGT" "GAGTG"
#> [33] "AGTGA" "GTGAA" "TGAAG" "GAAGA" "AAGAG" "AGAGA" "GAGAA" "AGAAG"
#> [41] "GAAGA" "AAGAG" "AGAGG" "GAGGA" "AGGAA" "GGAAA" "GAAAC" "AAACA"
#> [49] "AACAC" "ACACG" "CACGA" "ACGAC" "CGACA" "GACAC" "ACACG" "CACGA"
#> [57] "ACGAC" "CGACA" "GACAT" "ACATT" "CATTG" "ATTGC" "TTGCG" "TGCGA"
#> [65] "GCGAC" "CGACA" "GACAT" "ACATA" "CATAA" "ATAAT" "TAATG"
ИЯ могу найти счет с помощью
kmers %>%
imap(~ str_count(.y, .x))
, который возвращает
#> $CGGACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAA
#> [1] 1 1 1 1 1 1 4 1 1 1 1 1 2 2 3 3 4 1 1 1 1 1 2 2 3 3 4 1 1 1 1 1 1 1 1
#> [36] 3 3 4 2 1 1 1 4 2 1 1 1 1 1 1 1 2 2 2 4 1 2 2 2 4 2 1 1 1 1 1 1 4 2 1
#> [71] 1
#>
#> $GGACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAAT
#> [1] 1 1 1 1 1 4 1 1 1 1 1 2 2 3 3 4 1 1 1 1 1 2 2 3 3 4 1 1 1 1 1 1 1 1 3
#> [36] 3 4 2 1 1 1 4 2 1 1 1 1 1 1 1 2 2 2 4 1 2 2 2 4 2 1 1 1 1 1 1 4 2 1 1
#> [71] 1
#>
#> $GACTCGACAGATGTGAAGAAATGTGAAGACTGAGTGAAGAGAAGAGGAAACACGACACGACATTGCGACATAATG
#> [1] 1 1 1 1 4 1 1 1 1 1 2 2 3 3 4 1 1 1 1 1 2 2 3 3 4 1 1 1 1 1 1 1 1 3 3
#> [36] 4 2 1 1 1 4 2 1 1 1 1 1 1 1 2 2 2 4 1 2 2 2 4 2 1 1 1 1 1 1 4 2 1 1 1
#> [71] 1
Но теперь мне нужно вернуть каждый уникальный k-мер, который имеет счет 4. Мое единственное решение покавзять индекс каждого k-mer, равный 4, а затем регенерировать k-mer с помощью substr следующим образом:
kmers >%>
imap(~ str_count(.y, .x)) %>%
#test for k-mers that appear 4 times
map(function(y) {
map_lgl(y, function(x) x == 4)}) %>%
#Get the indexes of the matches
map(which) %>%
#Recreate the k-mers from each sequence
imap(function(a,b) {
map_chr(a, ~ substr(b, .x, .x + k -1))}) %>%
unlist %>%
unique
Что дает мне желаемый результат
#> 'CGACA' 'GAAGA'
Но это неэффективновыбросить k-mers и затем воссоздать их.Как я могу получить счетчики, но затем использовать их для фильтрации исходного списка k-мер?table()
работает, но я не могу понять, как работать с table()
, приводит к конвейеру dplyr, чтобы получить результат с простым списком строк, удовлетворяющих условию.