2017-01-26 6 views
1

У меня есть фрейм данных под названием lbt_all_epitopes из 38282 строк и трех столбцов, как показано ниже:R - не в состоянии хранить несколько выход из за цикл в векторе или данных кадре

sequence score epitope. 
1 RPGGPPGYRTPYTAK 1.724911 Epitope 
2 TQGDRQKIQDAVSAA 1.664611 Epitope 
3 EVKSRYNVDVSQNKR 1.593236 Epitope 
4 VIEMTRAFEDDDFDK 1.578200 Epitope 
5 ITQGDRQKIQDAVSA 1.533208 Epitope 
6 GSADLTPSNLTRPAS 1.532700 Epitope 

В первом столбце (с именем последовательность) У меня есть несколько похожих строк, которые я хочу удалить (я буду искать похожие строки, используя str_sub). Например, учитывая первую строку lbt_all_epitopes$sequence («RPGGPPGYRTPYTAK»), я хочу искать похожие строки во всем столбце и хранить их в vector или в data.frame, который будет называться to_be_removed. Я хочу сделать эту итерацию для первых 30 элементов, присутствующих в lbt_all_epitopes$sequence. Для простоты давайте рассмотрим пять верхних рядов. Когда я запускаю цикл, как показано ниже:

# Iterate over the first 5 rows 
top_30 <- 1:5 

for(i in top_30) { 
    print(agrep(str_sub(lbt_all_epitopes$sequence[i], start = 5, end = 11), lbt_all_epitopes$sequence, value = T)) 
} 

Выход:

[1] "RPGGPPGYRTPYTAK" "VGTRPGGPPGYRTPY" "TRPGGPPGYRTPYTA" "GGPPGYRTPYTAKPF" "PGGPPGYRTPYTAKP" 
[6] "LVGTRPGGPPGYRTP" "TLVGTRPGGPPGYRT" "GPPGYRTPYTAKPFV" "PPGYRTPYTAKPFVM" "GTRPGGPPGYRTPYT" 
[11] "PGYRTPYTAKPFVMC" 
[1] "TQGDRQKIQDAVSAA" "ITQGDRQKIQDAVSA" "GITQGDRQKIQDAVS" "NGITQGDRQKIQDAV" "QGDRQKIQDAVSAAS" 
[6] "QNGITQGDRQKIQDA" "GDRQKIQDAVSAASS" "VQNGITQGDRQKIQD" "DRQKIQDAVSAASSW" "RQKIQDAVSAASSWL" 
[11] "QKIQDAVSAASSWLE" 
[1] "EVKSRYNVDVSQNKR" "VKSRYNVDVSQNKRA" "NEVKSRYNVDVSQNK" "KSRYNVDVSQNKRAR" "LNEVKSRYNVDVSQN" 
[6] "YNVDVSQNKRARLRL" "RYNVDVSQNKRARLR" "MLNEVKSRYNVDVSQ" "SRYNVDVSQNKRARL" "HMLNEVKSRYNVDVS" 
[11] "EHMLNEVKSRYNVDV" 
[1] "VIEMTRAFEDDDFDK" "RVIEMTRAFEDDDFD" "GDRVIEMTRAFEDDD" "DRVIEMTRAFEDDDF" "IEMTRAFEDDDFDKF" 
[6] "RGDRVIEMTRAFEDD" "EMTRAFEDDDFDKFD" "FRGDRVIEMTRAFED" "MTRAFEDDDFDKFDR" "TRAFEDDDFDKFDRV" 
[11] "RAFEDDDFDKFDRVR" 
[1] "TQGDRQKIQDAVSAA" "ITQGDRQKIQDAVSA" "GITQGDRQKIQDAVS" "NGITQGDRQKIQDAV" "QGDRQKIQDAVSAAS" 
[6] "QNGITQGDRQKIQDA" "GDRQKIQDAVSAASS" "VQNGITQGDRQKIQD" "DVQNGITQGDRQKIQ" "DRQKIQDAVSAASSW" 
[11] "RQKIQDAVSAASSWL" 

именно то, что я хочу, т.е. распечатаны все подобные строки (11 на одну итерацию) к первой, второй , третий ... пятый элемент lbt_all_epitopes$sequence. Однако, когда я пытаюсь сохранить вывод в векторе (так называемый to_be_removed), со следующей петлей:

# create the empty vector where I will store the output 
to_be_removed <- c() 

for(i in top_30) { 
    to_be_removed[i] <- agrep(str_sub(lbt_all_epitopes$sequence[i], start = 5, end = 11), lbt_all_epitopes$sequence, value = T) 
} 

Я заметил, что каждая итерация производится только одну строку в качестве выхода (в отличие от 11 строк для каждого итерации), как показано ниже:

> to_be_removed 
[1] "RPGGPPGYRTPYTAK" "TQGDRQKIQDAVSAA" "EVKSRYNVDVSQNKR" "VIEMTRAFEDDDFDK" "TQGDRQKIQDAVSAA" 

было показано следующее предупреждение:

Warning messages: 
1: In to_be_removed[i] <- agrep(str_sub(lbt_all_epitopes$sequence[i], : 
    number of items to replace is not a multiple of replacement length 
2: In to_be_removed[i] <- agrep(str_sub(lbt_all_epitopes$sequence[i], : 
    number of items to replace is not a multiple of replacement length 
3: In to_be_removed[i] <- agrep(str_sub(lbt_all_epitopes$sequence[i], : 
    number of items to replace is not a multiple of replacement length 
4: In to_be_removed[i] <- agrep(str_sub(lbt_all_epitopes$sequence[i], : 
    number of items to replace is not a multiple of replacement length 
5: In to_be_removed[i] <- agrep(str_sub(lbt_all_epitopes$sequence[i], : 
    number of items to replace is not a multiple of replacement length 

я тогда предположить, что я СУИ пойте код, говорящий R, что он также должен конкатенировать все строки, созданные каждой итерацией, а затем перейти к следующей итерации. Кто-нибудь знает, как правильно сохранить вывод в vector, или даже в data.frame?

+1

Я уверен, что вы не можете хранить объект длиной> 1 в одной записи вектора. Почему бы не использовать список? Попробуйте что-то вроде 'to_be_removed <- lapply (lbt_all_epitopes $ sequence [1: 5], function (x) agrep (str_sub (x, start = 5, end = 11), lbt_all_epitopes $ sequence, value = T))' – LAP

+1

вы могли бы предоставить свой набор данных в виде 'dput (head (lbt_all_epitopes))'? – LAP

+0

Спасибо, он выполняет эту работу, как и адаптированный цикл от коллеги ниже. Вы знаете какой-либо другой способ хранения вывода в data.frame? В этом случае было бы лучше иметь фрейм данных, чтобы я мог искать строки в to_be_removed в моем исходном наборе данных (lbt_all_epitopes), чтобы удалить их. Благодарю. Да в следующий раз я буду писать с dput – BCArg

ответ

1

Чтобы избежать растущего for() -loop, мы можем использовать lapply(). Это должно быть быстрее при работе с огромными наборами данных.

to_be_removed <- lapply(lbt_all_epitopes$sequence[1:5], function(x) agrep(str_sub(x, start = 5, end = 11), lbt_all_epitopes$sequence, value = T)) 

дает список с извлеченными строками для каждой строки в отдельной строке списка:

[[1]] 
[1] "RPGGPPGYRTPYTAK" 

[[2]] 
[1] "TQGDRQKIQDAVSAA" "ITQGDRQKIQDAVSA" 

[[3]] 
[1] "EVKSRYNVDVSQNKR" 

[[4]] 
[1] "VIEMTRAFEDDDFDK" 

[[5]] 
[1] "TQGDRQKIQDAVSAA" "ITQGDRQKIQDAVSA" 

Теперь вы можете отделить тех, с strsplit() и unlist() их в вектор (которые вы могли бы использовать для подмножества):

to_be_removed <- unlist(lapply(to_be_removed, function(x) strsplit(x, " "))) 

Выход:

[1] "RPGGPPGYRTPYTAK" "TQGDRQKIQDAVSAA" "ITQGDRQKIQDAVSA" "EVKSRYNVDVSQNKR" "VIEMTRAFEDDDFDK" "TQGDRQKIQDAVSAA" 
[7] "ITQGDRQKIQDAVSA" 
+0

Отлично, это именно то, что я хочу! попробовал команду 'dput' из etiennekintzler (' dput (lbt_all_epitopes) '), и у меня что-то совсем другое. Знаете ли вы, почему? – BCArg

+0

Рад помочь!' dput() 'дает вам вывод для всего вашего фреймворка данных, который обычно довольно большой и, следовательно, код довольно длинный. Для примера для SO используйте либо 'dput (head (yourdata))', либо - если это недостаточно - вручную ограничьте размеры: 'dput (yourdata [1:20, 1: 5]) '. – LAP

2

Вы можете создать list:

# create the empty vector where I will store the output 
to_be_removed <- list() 

for(i in top_30) { 
    to_be_removed[[i]] <- agrep(str_sub(lbt_all_epitopes$sequence[i], start = 5, end = 11), lbt_all_epitopes$sequence, value = T) 
} 

Обратите внимание на двойной кронштейн для заполнения списка.

Также в следующий раз отправьте свои данные с помощью dput, чтобы мы могли использовать его напрямую. Для этого сделать: dput(lbt_all_epitopes), которая возвращает:

structure(list(X = 1:6, sequence = structure(c(4L, 5L, 1L, 6L, 
3L, 2L), .Label = c("EVKSRYNVDVSQNKR", "GSADLTPSNLTRPAS", "ITQGDRQKIQDAVSA", 
"RPGGPPGYRTPYTAK", "TQGDRQKIQDAVSAA", "VIEMTRAFEDDDFDK"), class = "factor"), 
    score = structure(c(6L, 5L, 4L, 3L, 2L, 1L), .Label = c("1.532700", 
    "1.533208", "1.578200", "1.593236", "1.664611", "1.724911" 
    ), class = "factor"), epitope. = structure(c(1L, 1L, 1L, 
    1L, 1L, 1L), .Label = "Epitope", class = "factor")), .Names = c("X", 
"sequence", "score", "epitope."), class = "data.frame", row.names = c(NA, 
-6L)) 
+0

, если я использую указанную вами команду, я получил: class = "factor"), score = c (1.7249113, 1.6646106, 1.5932359, 1.5782, 1.5332078, 1.5326996), эпитоп , = структура (c (1L, 1L, 1L, 1L, 1L, 1L), .Label = c ("Эпитоп", "Неэпитоп"), class = "factor")), .Names = c ("sequence ", " score "," epitope. "), Row.names = c (NA, 6L), class =" data.frame ") > Это вы имеете в виду? Спасибо, цикл выполняет эту работу, хотя было бы лучше сохранить вывод в data.frame. Любая идея о том, как это сделать? – BCArg

+0

Спасибо за предоставление 'dput()', @EtienneKintzler! – LAP

+1

Да 'dput()' действительно потрясающий @LeoP. Я нашел его на http://stackoverflow.com/questions/1295955/what-is-the-most-useful-r-trick , который вы можете проверить, вы можете узнать некоторые интересные функции. –

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

  • Нет связанных вопросов^_^