2014-12-23 4 views
3

У меня есть два кадра данных и я хочу использовать значение в одном (DF1$pos) для поиска по двум столбцам в DF2 (DF2start, DF2end), и если он попадает в эти числа, верните DF2$nameзначение поиска кадра данных в диапазоне и возвращает другой столбец

DF1

ID pos name 
chr 12 
chr 542 
chr 674 

DF2

ID start end annot 
chr  1 200  a1 
chr 201 432  a2 
chr 540 1002  a3 
chr 2000 2004  a4 

так что в этом примере я хотел бы DF1 стать

ID pos name 
chr 12 a1 
chr 542 a3 
chr 674 a3 

Я попытался с помощью слияния и пересекаются, но не знаете, как использовать if заявление с логическим выражением в них.

Кадры данных должны быть закодированы следующим образом,

DF1 <- data.frame(ID=c("chr","chr","chr"), 
       pos=c(12,542,672), 
       name=c(NA,NA,NA)) 

DF2 <- data.frame(ID=c("chr","chr","chr","chr"), 
       start=c(1,201,540,200), 
       end=c(200,432,1002,2004), 
       annot=c("a1","a2","a3","a4")) 
+0

Я не проголосовал за этот вопрос, но я думаю, что кто бы это ни делал, это потому, что вы не поместили свой фрейм данных es в формате R – user1945827

ответ

5

Может быть, вы можете использовать foverlaps из «data.table» пакета.

library(data.table) 
DT1 <- data.table(DF1) 
DT2 <- data.table(DF2) 
setkey(DT2, ID, start, end) 
DT1[, c("start", "end") := pos] ## I don't know if there's a way around this step... 
foverlaps(DT1, DT2) 
#  ID start end annot pos i.start i.end 
# 1: chr  1 200 a1 12  12 12 
# 2: chr 540 1002 a3 542  542 542 
# 3: chr 540 1002 a3 674  674 674 
foverlaps(DT1, DT2)[, c("ID", "pos", "annot"), with = FALSE] 
#  ID pos annot 
# 1: chr 12 a1 
# 2: chr 542 a3 
# 3: chr 674 a3 

Как отметил @Arun в комментариях, вы можете также использовать which = TRUE в foverlaps, чтобы извлечь соответствующие значения:

foverlaps(DT1, DT2, which = TRUE) 
# xid yid 
# 1: 1 1 
# 2: 2 3 
# 3: 3 3 
DT2$annot[foverlaps(DT1, DT2, which = TRUE)$yid] 
# [1] "a1" "a3" "a3" 
+0

Спасибо Ананде, это работает очарование. Очень признателен. – ScienceBuff

+0

@ Арун был бы способ «dplyr» достичь этого? –

+0

@ StevenBeaupré, нет совпадений, но используя 'between()' - check [this post] (http://stackoverflow.com/a/24480301/559784). Он материализует все соединение, а затем фильтрует. – Arun

2

Вы можете также использовать IRanges

source("http://bioconductor.org/biocLite.R") 
biocLite("IRanges") 
library(IRanges) 
DF1N <- with(DF1, IRanges(pos, pos)) 
DF2N <- with(DF2, IRanges(start, end)) 
DF1$name <- DF2$annot[subjectHits(findOverlaps(DF1N, DF2N))] 
DF1 
# ID pos name 
#1 chr 12 a1 
#2 chr 542 a3 
#3 chr 674 a3 
+1

Ницца. Однако использование пакета «GenomicRanges» может быть более актуальным, поскольку «IRanges» использует только диапазоны (без идентификаторов). Или вы должны использовать RangesList, я думаю, но GRanges намного удобнее. Q указывает только на одну хромосому, но я сомневаюсь, что это имеет место в реальном наборе данных. – Arun

+0

@Arun Спасибо за информацию. У меня нет установленного «GenomicRanges». Это проверит. – akrun

+0

@Arun Не могли бы вы добавить это как отдельный ответ? – akrun

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