#r #bioinformatics #panel-data #rollapply
Вопрос:
Поскольку я действительно новичок в R, я не уверен, смогу ли я правильно выразить свою проблему, поэтому заранее прошу прощения. У меня есть несколько букв, которые имеют заданное значение. Я создал для них фрейм данных, и у меня также есть строка с тем же набором букв. Я хочу сопоставить значения из фрейма данных каждой букве моей строки, а затем вычислить среднее значение для окна длины L. Я не могу найти способ выполнить первую часть, так как я не знаю, как сравнить строковые символы с символами фрейма данных, а затем присвоить значения строковым символам, чтобы найти среднее значение окна. Какие-нибудь советы?
A = data.frame(A = 0.429, C = -0.051, D = -2.024, E = -2.181, F = 0.836, G = 0.158, H = -1.056, I = 0.959, K = -2.398, L = 0.658, M = 0.470, N = -1.099, P = -0.675, Q = -1.564, R = -2.501, S = -0.292, T = -0.182, V = 0.634, W = 0.463, Y = 0.163) (a lt;- "MASEFKKKLFWRAVVAEF") a_split = strsplit(a, "") L = readline(prompt = "Enter window length: n") x = nchar(a) for(i in 1:x-L) { for(j in a_split) { } }
Правка 1: Хорошо, так что после вашей помощи я думаю, что добился некоторого прогресса. Извините за позднюю благодарность и ответ. Я хочу выполнить итерацию N(длина последовательности) — L(длина окна) 1, и, следовательно, мне нужны средние значения окон N — L 1. Затем я хочу, чтобы среднее значение каждого окна соответствовало самой центральной аминокислоте каждого окна, например, для первых 10 аминокислот среднее значение окна будет присвоено аминокислоте 5, затем для окна 2-11 аминокислоте 6 и т. Д.
`
А = С(а = 0.429, с = -0.051, Д = -2.024, е = -2.181, Ф = 0.836, г = 0.158 м, h = -1.056, я = 0.959, к = -2.398, л = 0.658, м = 0.470, Н = -1.099, Р = -0.675, м = -1.564, Р = -2.501, с = -0.292, Т = -0.182, в = 0.634, Вт = 0.463, г = 0.163) УНТ = 0
(a lt;- "MASEFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNV") a_split = strsplit(a, "") unlist(A)[ a_split[[1]] ] values lt;- A[ a_split[[1]] ] L=5 N = nchar(a) print(N) for(i in 1:N-L) { print(convolve(values, rep(i,i L-1) / L, type ="filter")) print(i/2) cnt = cnt 1 } print(cnt)
`
Поскольку я не знаком с R, я не совсем понимаю, как работает свертка, и это моя главная проблема.
Правка 2: Я думаю, вы правильно поняли мой вопрос, и я благодарю вас за это. У меня есть последовательность из N элементов, и я хочу посмотреть, есть ли в этой последовательности части, соответствующие определенным критериям. По этой причине я хочу иметь окно длиной 10 для поиска по последовательности. Для каждого окна среднее значение будет присвоено «центральному» элементу (я знаю, что 5.5 математически является центром, но округление здесь идеально).
После завершения всех итераций я хочу просмотреть значения каждого окна и посмотреть, есть ли в списке результатов по крайней мере L/2 элемента в последовательности с положительным значением. Например, если в результатах существует подпоследовательность, подобная [«5» = 0.5, «6» = 2.35, «7» = 0.15, «8» = 0.35, «9» = 0.5],т. е. по крайней мере 5 элементов в последовательности с положительным значением, тогда эта часть последовательности (5-9), возможно, является трансмембранной областью. Конечно, если есть более последовательно положительные значения, критерии по — прежнему применимы. Моя цель состоит в том, чтобы найти эти области, которые могли бы быть трансмембранными областями.
Я надеюсь, что смогу выполнить последнюю часть, так как она не включает свертку, которая по какой-то причине действительно доставила мне много хлопот.
Я действительно благодарен вам за помощь!
Комментарии:
1. Второй аргумент to
convolve()
похож на вес иconvolve
вычисляет взвешенную суммуvalues
по окну. Выберите вес , чтобы каждый элемент в окне был взвешен как1 / window_size
,rep(1, window_size) / window_size
т. е. , чтобы взвешенная сумма была просто средним значением. Я думаю, что простой результатconvolve(values, rep(1, window_size) / window_size, type = "filter")
-это именно то, что вы хотите (среднее значение в каждом окне), но для определения местоположения окна используется первая буква окна, а не средняя буква.2. Когда я использую rep(1, window_size) / window_size, я получаю средние значения для каждого элемента. Я хочу распечатать и рассчитать средние значения для элементов каждого окна. Например, 1-10, 2-11, 3-12 и т.д., И среднее значение первого окна будет для элемента 5. Я попытался изменить параметры в rep, но это сработало не так, как ожидалось. Я набрал: rep(i, размер окна) / размер окна, а также изменил параметр values на значения[i:i L] .
3. Я обновил свой ответ, чтобы более полно показать свое понимание вашего вопроса. Если я не понимаю, то, возможно, вы могли бы проиллюстрировать «вручную» в своем вопросе, что вы ожидаете, по крайней мере, для нескольких аминокислот.
Ответ №1:
Вы можете сделать это в одну строку, используя свой оригинальный формат данных:
sapply(unlist(strsplit(a, "")), (i) A[[i]]) #gt; M A S E F K K K L #gt; 0.470 0.429 -0.292 -2.181 0.836 -2.398 -2.398 -2.398 0.658 #gt; F W R A V V A E F #gt; 0.836 0.463 -2.501 0.429 0.634 0.634 0.429 -2.181 0.836
Или, если вам не нужны буквенные индексы, однострочный:
as.numeric(sapply(unlist(strsplit(a, "")), (i) A[[i]])) #gt; [1] 0.470 0.429 -0.292 -2.181 0.836 -2.398 -2.398 -2.398 0.658 #gt; [10] 0.836 0.463 -2.501 0.429 0.634 0.634 0.429 -2.181 0.836
Ответ №2:
Для исходного фрейма data.frame вы можете написать unlist(A)[ a_split[[1]] ]
.
Но вместо использования фрейма данных используйте именованный числовой вектор,
A = c(A = 0.429, C = -0.051, D = -2.024, E = -2.181, F = 0.836, G = 0.158, H = -1.056, I = 0.959, K = -2.398, L = 0.658, M = 0.470, N = -1.099, P = -0.675, Q = -1.564, R = -2.501, S = -0.292, T = -0.182, V = 0.634, W = 0.463, Y = 0.163)
Затем используйте это как «карту» между буквами и значениями
values lt;- A[ a_split[[1]] ] values # M A S E F K K K L F W # 0.470 0.429 -0.292 -2.181 0.836 -2.398 -2.398 -2.398 0.658 0.836 0.463 # R A V V A E F # -2.501 0.429 0.634 0.634 0.429 -2.181 0.836
Используйте convolve()
для расчета среднего значения скользящего окна
gt; window_size = 10 gt; result lt;- convolve(values, rep(1, window_size) / window_size, type = "filter") gt; result M A S E F K K K L F -0.6438 -0.6445 -0.9375 -0.8654 -0.5839 -0.6041 -0.3214 -0.2997 0.0237 0.0237 W R A V V A E F L A -0.0170 -0.0815 0.1504 0.1733 0.1935 0.1935 0.2342 0.5482 0.4354 0.4655 T T L F V F I S I G 0.4384 0.4274 0.4885 0.4885 0.4207 0.4409 0.1175 0.0379 -0.0004 -0.0329 S A L G F K Y P V G -0.0329 -0.1136 -0.2664 -0.4886 -0.5226 -0.5633 -0.2601 -0.4328 -0.5677 -0.7410 N -0.6934
Обратите внимание, что первым элементом результата является среднее значение элементов 1:10, вторым-среднее значение элементов 2:11 и т. Д
gt; mean(values[1:10]) [1] -0.6438 gt; mean(values[2:11]) [1] -0.6445 gt; mean(values[3:12]) [1] -0.9375
Я полагаю, что вы говорите, что хотели бы, чтобы окна назывались по-другому, используя 5-е, 6-е, … имена вместо первого, второго, … так что
gt; names(values)[5:(length(values) - 5)] [1] "F" "K" "K" "K" "L" "F" "W" "R" "A" "V" "V" "A" "E" "F" "L" "A" "T" "T" "L" [20] "F" "V" "F" "I" "S" "I" "G" "S" "A" "L" "G" "F" "K" "Y" "P" "V" "G" "N" "N" [39] "Q" "T" "A"
так
gt; names(result) lt;- names(values)[5:(length(values) - 5)] gt; result F K K K L F W R A V -0.6438 -0.6445 -0.9375 -0.8654 -0.5839 -0.6041 -0.3214 -0.2997 0.0237 0.0237 V A E F L A T T L F -0.0170 -0.0815 0.1504 0.1733 0.1935 0.1935 0.2342 0.5482 0.4354 0.4655 V F I S I G S A L G 0.4384 0.4274 0.4885 0.4885 0.4207 0.4409 0.1175 0.0379 -0.0004 -0.0329 F K Y P V G N N Q T -0.0329 -0.1136 -0.2664 -0.4886 -0.5226 -0.5633 -0.2601 -0.4328 -0.5677 -0.7410 A -0.6934
Может быть, если вы имеете в виду что-то другое, вы могли бы отредактировать свой исходный вопрос, включив в него пример, рассчитанный вручную.
Один небольшой момент заключается в том, что » 5 » не находится в середине последовательности 1-10, середина равна 5,5…