Фильтрация R data.frame на основе нескольких ограничений

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

У меня есть фреймворк с 78 812 строками. В столбце PeakName у меня есть идентификаторы, указывающие на «пик» в моих данных. Всего 13000 пиков, поэтому каждый пик часто появляется в кадре данных несколько раз. Для каждого уникального PeakName есть несколько motifs с разными значениями PValue, связанными с ними. У каждого мотива также есть start и stop расположение.

Моя цель - создать новый фрейм данных, в котором:

  1. для каждого PeakName я нахожу motif с наименьшим PValue и добавляю его в новый фрейм данных
  2. используя места start и stop для мотивов, я обнаруживаю, есть ли какие-либо мотивы, перекрывающие тот, который был только что добавлен в новый фрейм данных. Если есть, я удаляю их как возможности для добавления в новый фрейм данных.
  3. если для этого PeakName осталось motifs, я возвращаюсь к шагу 1 и повторяю этот процесс до тех пор, пока не останется больше motifs возможных motifs.
  4. ПРИМЕЧАНИЕ: если есть два пика с равным PValue, где это значение в настоящее время является самым низким значением, я бы выбрал «Основной» мотив вместо «Вторичного» мотива.

Пример (упрощенный) данных:

Motif      Start   Stop    PValue     PeakName
Primary    4       10      5          Peak1
Primary    5       11      4          Peak1
Secondary  12      18      8          Peak1
Secondary  8       16      6          Peak1
Primary    12      18      9          Peak1
Secondary  3       9       7          Peak2
Primary    5       11      7          Peak2

Желаемый результат вышеперечисленных данных:

Motif      Start   Stop    PValue     PeakName
Primary    5       11      4          Peak1
Secondary  12      18      8          Peak1
Primary    5       11      7          Peak2

Любой совет был бы очень признателен, так как я был сбит с толку тем, как написать что-то для этого, и это задача, которую я считаю, должна быть довольно простой, но продолжает ускользать от меня. Спасибо!


person Rene    schedule 25.03.2016    source источник
comment
Я не думаю, что вы объяснили в своей голове правила, которые позволили вам произвести такой результат. Должны ли мы придавать различный вес первичным и вторичным мотивам? Почему Secondary 3 9 7 Peak2 не подходит для включения? Почему была выбрана вторая строка в первом перекрытии (строки 1 и 2), но выбрана первая строка во втором перекрытии (строки 3 и 4). Программирование требует гораздо большего, чем понимание синтаксиса. Наиболее важно это требует четкого, недвусмысленного описания проблемы.   -  person IRTFM    schedule 25.03.2016
comment
Secondary 3 9 7 Peak2 не подходит для включения в соответствии с правилом (4), потому что он имеет такое же PValue, что и основной мотив в Peak2, но в этом случае я бы отдал приоритет первичному, а не вторичному. Вторая строка была выбрана из-за всех значений PV Peak1, она имеет наименьшее значение. Строка сначала выбирается по минимальному значению PValue, которое находится во второй строке. Это перекрывается с первой, четвертой и пятой строками, поэтому эти строки не были включены в окончательный вывод. Извините, я думал, что мое объяснение было более ясным, чем кажется   -  person Rene    schedule 25.03.2016


Ответы (1)


Вы можете немного очистить, чтобы уловить крайние случаи, такие как галстуки. Обратите внимание на использование вспомогательного столбца для выбора основного / дополнительного мотива:

df2 <- {}
for (peak in unique(df$PeakName)) {
    tmp <- subset(df, PeakName==peak)
    tmp$helper <- tmp$Pvalue + ifelse(tmp$Motif=="S", 0.1, 0)

    while (nrow(tmp) > 0) {
        ind <- which.min(tmp$helper)
        df2 <- rbind(df2, tmp[ind,])
        remove <- (tmp$Start >= tmp$Start[ind] & tmp$Start <= tmp$Stop[ind]) | (tmp$Stop >= tmp$Start[ind] & tmp$Stop <= tmp$Stop[ind])
        tmp <- tmp[!remove,]
    }
}
person fanli    schedule 25.03.2016
comment
какие-либо предложения о том, как изменить столбец «помощник» при выборе мотива, если у меня есть 6 разных мотивов вместо двух? В одном из моих файлов у меня есть: Tbr_prim_8bp, Tbr_prim_12bp, Tbr_sec_8bp, Tbr_sec_12bp, Smad3_prim, Smad3_sec, и это порядок, в котором я хотел бы расставить приоритеты в этом состоянии. - person Rene; 27.03.2016
comment
Добавьте 0,1, 0,2, ..., 0,6 в соответствующем порядке. - person fanli; 28.03.2016
comment
Думаю, я немного запутался в том, как будет работать оператор ifelse? Вы подразумеваете, что мне понадобится уникальный идентификатор для каждого из моих мотивов, сопровождаемый 0,1, 0,2 и т. Д. В том порядке, в котором я хотел бы ранжировать мотивы? Значит, мне понадобятся tmp$helper <- tmp$Pvalue + ifelse(tmp$Motif=="Tbr_prim_8bp", 0.1, 0), а также tmp$helper <- tmp$Pvalue + ifelse(tmp$Motif=="Tbr_prim_12bp", 0.2, 0) и т. Д.? - person Rene; 28.03.2016
comment
Вместо этого вы можете использовать вектор: motif_lookup <- seq(0.1,0.6,0.1); names(motif_lookup) <- c("Tbr_prim_8bp", "Tbr_prim_12bp", ...); tmp$helper <- tmp$Pvalue + motif_lookup[tmp$Motif] - person fanli; 28.03.2016