169 похожих чатов

Добрый день, коллеги. Здесь же можно задавать вопросы о качестве

кода в плане восприятия/оптимальности и вообще стилистики? Поскольку задача решена, но нет уверенности, что так делать хорошо и правильно.
Суть в следующем: есть две последовательности ДНК (строки), в которых есть различия на определенных позициях. Последовательности должны быть одной длины и моя задача определить, в каких позициях произошли замены. Однако, поскольку это ДНК, то в зависимости от позиции относительно рамки считывания, будет различаться конечный результат замены. Нуклеотиды считываются по 3, поэтому есть три возможных ситуации: замена в первой позиции, во второй и в третьей относительно старта. В своей реализации использую case_when для проверки остатка от деления на три и выписываю результат.

Вопрос, насколько это адекватно и понятно?
r
library(purrr)
library(stringr)
library(dplyr)

ref_seq <- 'ATGACCCCAATACGCAA'
mut_seq <- 'ATGTCCGCAATGCGCAA'

ref_seq <- unlist(strsplit(ref_seq, ''))
mut_seq <- unlist(strsplit(mut_seq, ''))

res <- map2_chr(ref_seq, mut_seq, .f = ~ifelse(.x == .y, "", paste(.x, .y, sep = "_to_")))
mutation_indeces <- str_which(res, '')
gene_code <- list('UUU' = 'Phe', 'UUC'='Phe', 'UCU'='Ser', 'UCC'='Ser',
'UAU'='Tyr', 'UAC'='Tyr', 'UGU'='Cys', 'UGC'='Cys',
'UUA'='Leu', 'UCA'='Ser', 'UAA'='stop', 'UGA'='stop',
'UUG'='Leu', 'UCG'='Ser', 'UAG'='stop', 'UGG'='Trp',
'CUU'='Leu', 'CUC'='Leu', 'CCU'='Pro', 'CCC'='Pro',
'CAU'='His', 'CAC'='His', 'CGU'='Arg', 'CGC'='Arg',
'CUA'='Leu', 'CUG'='Leu', 'CCA'='Pro', 'CCG'='Pro',
'CAA'='Gln', 'CAG'='Gln', 'CGA'='Arg', 'CGG'='Arg',
'AUU'='Ile', 'AUC'='Ile', 'ACU'='Thr', 'ACC'='Thr',
'AAU'='Asn', 'AAC'='Asn', 'AGU'='Ser', 'AGC'='Ser',
'AUA'='Ile', 'ACA'='Thr', 'AAA'='Lys', 'AGA'='Arg',
'AUG'='Met', 'ACG'='Thr', 'AAG'='Lys', 'AGG'='Arg',
'GUU'='Val', 'GUC'='Val', 'GCU'='Ala', 'GCC'='Ala',
'GAU'='Asp', 'GAC'='Asp', 'GGU'='Gly', 'GGC'='Gly',
'GUA'='Val', 'GUG'='Val', 'GCA'='Ala', 'GCG'='Ala',
'GAA'='Glu', 'GAG'='Glu', 'GGA'='Gly', 'GGG'='Gly')
translate_codon <- function(start_coord, end_coord, string) {
gene_code[[gsub('T', 'U', paste0(string[start_coord:end_coord], collapse = ''))]]
}
map(mutation_indeces, .f = ~case_when(
.x %% 3 == 1 ~ c(res[.x], .x, translate_codon(.x, (.x+2), ref_seq),
translate_codon(.x, (.x+2), mut_seq)),
.x %% 3 == 2 ~ c(res[.x], .x, translate_codon((.x-1), (.x+1), ref_seq),
translate_codon((.x-1), (.x+1), mut_seq)),
.x %% 3 == 0 ~ c(res[.x], .x, translate_codon((.x-2), (.x), ref_seq),
translate_codon((.x-2), (.x), mut_seq))))
#> [[1]]
#> [1] "A_to_T" "4" "Thr" "Ser"
#>
#> [[2]]
#> [1] "C_to_G" "7" "Pro" "Ala"
#>
#> [[3]]
#> [1] "A_to_G" "12" "Ile" "Met"


<sup>Created on 2022-05-18 by the reprex package (v2.0.1)</sup>

5 ответов

21 просмотр

Можно попробовать подключить Biostrings. Там большинство стандартных задач для работы с биологическими последовательностями решаются (та же трансляция). Уж генетический код вручную точно можно не задавать.

Dmitry
Можно попробовать подключить Biostrings. Там больш...

один минус — подключение биокондуктора сносит весь устоявшийся набор пакетов и глаголов в небытие. там полностью свой мир.

Глянул. Я бы написал примерно так. Атомарные верифицируемые шаги. Исходный вариант хорош для демонстрации владения различными методами. Но там отсутствует валидация и многие шаги тяжело проследить без дебага или знания нюансов функций, таких как "An empty pattern, '', is equivalent to boundary('character')." в str_which, а также избыточности под капотом. library(data.table) library(magrittr) ref_seq <- 'ATGACCCCAATACGCAA' mut_seq <- 'ATGTCCGCAATGCGCAA' gene_code <- list('UUU'='Phe', 'UUC'='Phe', 'UCU'='Ser', 'UCC'='Ser', 'UAU'='Tyr', 'UAC'='Tyr', 'UGU'='Cys', 'UGC'='Cys', 'UUA'='Leu', 'UCA'='Ser', 'UAA'='stop', 'UGA'='stop', 'UUG'='Leu', 'UCG'='Ser', 'UAG'='stop', 'UGG'='Trp', 'CUU'='Leu', 'CUC'='Leu', 'CCU'='Pro', 'CCC'='Pro', 'CAU'='His', 'CAC'='His', 'CGU'='Arg', 'CGC'='Arg', 'CUA'='Leu', 'CUG'='Leu', 'CCA'='Pro', 'CCG'='Pro', 'CAA'='Gln', 'CAG'='Gln', 'CGA'='Arg', 'CGG'='Arg', 'AUU'='Ile', 'AUC'='Ile', 'ACU'='Thr', 'ACC'='Thr', 'AAU'='Asn', 'AAC'='Asn', 'AGU'='Ser', 'AGC'='Ser', 'AUA'='Ile', 'ACA'='Thr', 'AAA'='Lys', 'AGA'='Arg', 'AUG'='Met', 'ACG'='Thr', 'AAG'='Lys', 'AGG'='Arg', 'GUU'='Val', 'GUC'='Val', 'GCU'='Ala', 'GCC'='Ala', 'GAU'='Asp', 'GAC'='Asp', 'GGU'='Gly', 'GGC'='Gly', 'GUA'='Val', 'GUG'='Val', 'GCA'='Ala', 'GCG'='Ala', 'GAA'='Glu', 'GAG'='Glu', 'GGA'='Gly', 'GGG'='Gly') translateCodon <- function(vec){ gene_code[[gsub('T', 'U', paste0(vec, collapse = ''))]] } dt <- data.table(ref = ref_seq, mut = mut_seq) %>% .[, lapply(.SD, function(x){unlist(strsplit(x, ""))})] %>% .[, `:=`(grp = (.I - 1) %/% 3, is_noneq = (ref != mut))] %>% .[, `:=`(n_diff = sum(is_noneq), n = .N, idx = .I), by = grp] %>% # санация неполных триплетов + оставляем только измененные наборы # вопрос про допустимое количество изменений! .[n == 3 & n_diff == 1] # соберем словарик генов по группам dict_dt <- dt[, .(ref_gene = translateCodon(ref), mut_gene = translateCodon(mut)), by = grp] # делаем свертку res_dt <- merge(dt[is_noneq == TRUE], dict_dt, by = "grp") glue::glue_data(res_dt, "{ref}->{mut}, @{idx}, {ref_gene}->{mut_gene}") #> A->T, @4, Thr->Ser #> C->G, @7, Pro->Ala #> A->G, @12, Ile->Met

Elena-V Автор вопроса
Ilya Shutov
Глянул. Я бы написал примерно так. Атомарные вериф...

Спасибо, решение действительно изящное, правда синтаксис дт пока еще не освоен, поэтому читалось сложно, но при применении шагов все достаточно понятно. Решение конечно отправлю свое, но на заметку взяла такой дататейбл подход

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта