2016-10-24 5 views
1

У меня есть два кадра данных, SCR и SpecpecSpecies. Названия предметов в SCR частично содержат виды, перечисленные в Специфических видах.Эффективный способ перебора двух списков (альтернатива вложенного цикла)

SpecificSpecies$Species 
S cerevisiae 
Daucus carota 

SCR$MESH_HEADINGS 
tetracycline CMT-3 
zrg17 protein, S cerevisiae 
EP4 glycoprotein, Daucus carota 

Я пытаюсь получить подмножество SCR, содержащее только те записи, которые не имеют соответствующих видов. В приведенном выше случае, этот список будет только

tetracycline CMT-3. 

Как я научился делать это будет с помощью вложенных циклов, сравнивая каждую запись в SCR для каждой записи в SpecificSpecies. Когда совпадение не найдено, добавьте строку SCR в новую таблицу:

For each row in SCR { 
    SpeciesNumber <- 1 
    match <-NULL 
    while ((is.null(match)) & (SpeciesNumber < length(SpecificSpecies$Species))) { 
    if (grepl(SpecificSpecies$Species[SpeciesNumber], SCR[row,]$MESH_HEADING)){ 
    match <- TRUE} 
    SpeciesNumber <- SpeciesNumber + 1} 
    if ((is.null(match) & SpeciesNumber == length(SpecificSpecies$Species)) { 
    speciesNoMatch = rbind(speciesNoMatch, SCR[row])} 
}} 

Но это мучительно медленно с 65000 записей в SCR и около 1500 в SpecificSpecies. Есть ли способ гнездиться, как это, с лапкой? Или какая-то другая функция, которая поможет здесь, с которой я не знаком?

Я уверен, что это ужасный код для начала. Я медицинский библиотекарь, который иногда использует R для анализа данных, поэтому у меня очень ограниченные навыки программирования, но обычно это не имеет значения, являются ли мои решения уродливыми или неэффективными, пока они в конечном итоге работают. Я знаю, что должен быть лучший способ сделать это; простите меня за то, что я не знаю чего-то, что, вероятно, простое решение.

ответ

0

Я думаю !(%in%) будет делать трюк:

SpecificSpecies <- data.frame(
    Species = c("S cerevisiae", "Daucus carota"), 
    stringsAsFactors = FALSE 
) 

SCR <- data.frame(
    MESH_HEADINGS = c("tetracycline CMT-3", "zrg17 protein", "S cerevisiae", 
        "EP4 glycoprotein", "Daucus carota"), 
    stringsAsFactors = FALSE 
) 


SCR[!(SCR$MESH_HEADINGS %in% SpecificSpecies$Species), , drop = FALSE] 
#  MESH_HEADINGS 
# 1 tetracycline CMT-3 
# 2  zrg17 protein 
# 4 EP4 glycoprotein 

, , drop = ... не опечатка. Первый , обеспечивает возврат всех столбцов/переменных. Второй , drop = FALSE гарантирует, что возвращаемый результат по-прежнему является фреймом данных.

Коррекция

Хорошо, я только что заметил, что вы хотите grep с Species. Следующий код должен работать:

SpecificSpecies <- data.frame(
    Species = c("S cerevisiae", "Daucus carota"), 
    stringsAsFactors = FALSE 
) 

SCR <- data.frame(
    MESH_HEADINGS = c("tetracycline CMT-3", 
        "zrg17 protein, S cerevisiae", 
        "EP4 glycoprotein, Daucus carota"), 
    stringsAsFactors = FALSE 
) 

matching <- lapply(SpecificSpecies$Species, function(x) { 
    grep(x, SCR$MESH_HEADINGS) 
}) 

SCR[-(unlist(matching)), ] 
#  MESH_HEADINGS 
# 1 tetracycline CMT-3 

lapply() использует анонимную функцию, чтобы определить шаблон совпадает. Он перемещается по каждому виду и сравнивает его с каждым пунктом SCR$MESH_HEADINGS. Он возвращает список совпадающих индексов.

Подмножество ([]) просто сбрасывает совпадающие индексы (-) после того, как мы сначала установили согласованные индексы, чтобы сделать его совместимым с функцией подмножества.

+0

Нет, боюсь, что нет. Эти запятые не являются разделителями, они являются частью исходной строки. То есть, некоторые из записей принимают форму «имя Protien, название вида». Мне нужно использовать grep или regex или что-то вроде этого, чтобы обеспечить совпадения, так как вид будет соответствовать только части SCR $ MESH_HEADING. – NotMyJob

+0

@NotMyJob Я только что заметил, посмотрю мое редактирование – Phil

+0

Спасибо за помощь! Две вещи. Во-первых, ваш пример работает для меня, но не удается, когда я пытаюсь использовать свои фактические данные. Я получаю список 0s, а затем пустую таблицу в списке. Любая идея почему? Во-вторых, мне нужна вся запись из SCR, когда я подмножаюсь, а не только MESH_HEADING. Есть ли простой способ сделать это возвратом всей строки? – NotMyJob

0

Основная идея:

Выполнение петли на SpecificSpecies как она имеет меньше строк. Поскольку временная рамка SCR будет уменьшена, сделайте это рекурсивно, поэтому цикл будет работать с меньшим количеством данных каждый раз.

В целом упаковки data.table или plyr увеличить производительность. Здесь решение с data.table

library(data.table) 
SpecificSpecies <- data.frame(Species = c("S cerevisiae", "Daucus carota"),stringsAsFactors = FALSE) 
SCR <- data.frame(MESH_HEADINGS = c("tetracycline CMT-3", "zrg17 protein, S cerevisiae","EP4 glycoprotein Daucus carota"),stringsAsFactors = FALSE) 

dt_temp <- data.table(SCR) 
for (species in SpecificSpecies$Species) { 
    dt_temp <- dt_temp[!grepl(species,dt_temp$MESH_HEADINGS), ] 
} 
dt_result <- dt_temp 
dt_result 
+0

@NotMyJob работает так быстро, как вы хотите? можете ли вы отметить, как разрешено? – timat

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

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