2017-02-08 4 views
1

У меня есть фрейм данных под названием tabelao, который выглядит как продукции, произведенной dput(head(tabelao):R - петля в петлю, чтобы извлечь несколько комбинаций строк для нескольких строк в кадре данных

structure(list(sequence = c("prot0", "prot1", "prot2", "prot3", "prot4", "prot5"), start = c(282L, 219L, 641L, 355L, 635L, 526L), end = c(325L, 273L, 682L, 370L, 662L, 560L), length = c(44L, 55L, 42L, 16L, 28L, 35L), AGI = c(1103L, 962L, 869L, 847L, 799L, 736L), AGR = c(25L, 17L, 20L, 52L, 28L, 21L), epitope = c("SEFKECFKEVNYDMSYFIRTTNPRETKLVQDIWKKZUTKGDWWQL", "SYAGFEQQRKKFDNPKLKILNVELELKAEKDNPOPRLKDPKQYQSIVDLPOKIIF", "RLEDNPAQWEREKSDEPALLHKELAERRAQQLKJMNRRLANQ", "AYATLOKIQQWKVRKS", "ASCSVKLGLWKNAPOLQWNALELVPDHP", "KKAERCEDPNAWKGPTNGGPOIUQNAGDGAFYGPK"), comb_per_epitope = c(30, 41, 28, 2, 14, 21)), .Names = c("sequence", "start", "end", "length", "AGI", "AGR", "epitope", "comb_per_epitope"), row.names = c(NA, 6L), class = "data.frame") 

То, что я хочу сделать, это следующий. В каждой строке tabelao у меня есть на tabelao$epitope строка (символ) с переменной длиной. Из каждой строки (у моего tabelao всего 241 строки) Я хочу получить все возможные строки из 15 символов. Обратите внимание, что я не хочу палиндромных последовательностей. Для того, чтобы получить все эти последовательности (число последовательностей, в зависимости от длины струны рассчитывали по длине -15 + 1, и это можно увидеть на tabelao$comb_per_epitope) Я использовал следующий цикл:

combinations <- c() 
for(i in 1:tabelao$comb_per_epitope[1]) { combinations[i] <- str_sub(string = tabelao$epitope[1], start = i, end 
    = i+14) } 

и я получил whtat я хотел то есть 30 возможных комбинаций из 15 символов:

> combinations 
[1] "SEFKECFKEMNYDMN" "EFKECFKEMNYDMNY" "FKECFKEMNYDMNYF" "KECFKEMNYDMNYFI" "ECFKEMNYDMNYFIR" "CFKEMNYDMNYFIRT" "FKEMNYDMNYFIRTT" 
[8] "KEMNYDMNYFIRTTN" "EMNYDMNYFIRTTNP" "MNYDMNYFIRTTNPT" "NYDMNYFIRTTNPTH" "YDMNYFIRTTNPTHE" "DMNYFIRTTNPTHEK" "MNYFIRTTNPTHEKL" 
[15] "NYFIRTTNPTHEKLV" "YFIRTTNPTHEKLVQ" "FIRTTNPTHEKLVQD" "IRTTNPTHEKLVQDI" "RTTNPTHEKLVQDIW" "TTNPTHEKLVQDIWK" "TNPTHEKLVQDIWKK" 
[22] "NPTHEKLVQDIWKKL" "PTHEKLVQDIWKKLE" "THEKLVQDIWKKLEA" "HEKLVQDIWKKLEAK" "EKLVQDIWKKLEAKG" "KLVQDIWKKLEAKGD" "LVQDIWKKLEAKGDI" 
[29] "VQDIWKKLEAKGDIY" "QDIWKKLEAKGDIYL" 

Но опять же, я мог управлять только сделать это для первой строки. Теперь я хочу повторить это по 241 строкам tabelao. Я попытался поставить петлю внутри другого цикла без успеха. В дополнение к этому tabelao, у меня также есть list под названием vetores, который содержит, считая каждую строку tabelao, числовую последовательность, начиная с 1 и заканчивая числом возможных комбинаций, как показано ниже (я использовал этот список в своих циклах, как будет показано ниже):

> head(vetores) 

[[1]] 
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 

[[2]] 
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 

[[3]] 
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 

[[4]] 
[1] 1 2 

[[5]] 
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 

[[6]] 
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 

Мой "двойную петлю" выглядеть следующим образом:

trial <- c() # I'll store the output of each iterations in this object 
for(i in 1:nrow(tabelao)){ # I want 241 iterations, which is the length of tabelao 
    trial[i] <- for(each in 1:tabelao$comb_per_epitope[i]) { 
    str_sub(string = tabelao$epitope[each], start = vetores[[each]][each], end = vetores[[each+14]][each+14]) 
    }               
} 

выход был просто NULL:

> trial 
NULL 

Может ли кто-нибудь определить, что я делаю неправильно? Я знаю, что цикл в цикле действительно не рекомендуется. Однако я не знаком с семейством функций apply.

+0

Try: 'Map (функция (х, у) подстрока (х, seq_len (у), seq_len (у) +14), tabelao $ эпитоп, tabelao $ comb_per_epitope)'. – nicola

+1

'str_sub' не является базовой функцией R. Если вы используете какие-либо пакеты, включите их в свой вопрос выше. Может быть, вам нужна база R 'substr' вместо? – lmo

+0

да, извините, я забыл упомянуть, из какого пакета это (stringr) – BCArg

ответ

1

Ниже двойная петля работает для меня:

trial <- list() 

for(j in 1:nrow(tabelao)){ 
    combinations <- c() 
    for(i in 1:tabelao$comb_per_epitope[j]) { 
    combinations[i] <- str_sub(string = tabelao$epitope[j], 
    start = i,end = i+14) 
    trial[[j]] <- combinations 
    } 

} 

Вы должны проверить применить, sapply, lapply и т.д ... Такого рода задачи могут быть обработаны гораздо более эффективно, таким образом. В частности, если эти data.frame большие. Рассмотрим обертывание цикл извлечения строки в функции, а затем apply'ing его к data.frame

Например, можно также добиться этого с помощью ниже:

# Wrap the string extraction in a function 
string15 <- function(df){ 

    # Define combinations as vector 
    combinations <- c() 
    for(i in 1:df$comb_per_epitope) { # Use for loop to loop through  combinations 
     combinations[i] <- str_sub(string = df$epitope, start = i, end 
                     = i+14) 
     } 
    # Return the combinations 
    return(combinations) 
} 

# Split your dataframe by sequence to get a list of dataframes where each element of the list represents a row of the data.frame 
tabelao.splits <- split(tabelao, as.factor(tabelao$sequence)) 

# Define a list to hold the results and lapply your function 
res <- list() 
res <- lapply(tabelao.splits, string15) 
+0

Отлично, это сработало и для меня. Действительно, я недавно взглянул на функции «apply», и они действительно иногда обрабатывают данные легче, чем циклы. – BCArg

+1

Рад, что это сработало, применять семейство функций, безусловно, нужно немного привыкнуть, но это стоит усилий. – GarAust89

1

I d»использовать rollapply из zoo пакета , В этом случае мы разделим каждую строку на '' и применим функцию rollapply в каждой строке. rollapply применяет функцию paste к индексам прокатки каждой строки. Поэтому для каждой строки это вставляет [1:15], [2:16], [3:17] и т. Д. Наконец, мы используем Map с length<- (как функция, следовательно, обратные), чтобы задать длину, основанную на переменной comb_per_epitope.

library(zoo) 
Map(`length<-`, lapply(strsplit(tabelao$epitope, ''), function(i) 
         rollapply(i, 15, by = 1, paste, collapse = '')), tabelao$comb_per_epitope) 
+0

Хотя я вообще не знаком с этой функцией, она выполняла эту работу. Спасибо – BCArg

+1

Он в основном применяет функцию к индексам прокатки, поэтому здесь он применяет 'paste' к строке 1 [1:15], [2:16], [3, 17] и т. Д. – Sotos

+0

, что выглядит удобно , будет иметь более пристальный взгляд – BCArg

Смежные вопросы