Два кадра данных, идентификаторы соединения и позиция от одного df, если значение находится в диапазоне 2nd df - PullRequest
0 голосов
/ 09 октября 2019

Со вчерашнего дня я пытаюсь решить свою проблему ... Я думаю, лучшее объяснение будет, когда я покажу вам пример, поэтому у меня есть два df's x и y, и они выглядят так:

ID_x <- c('x1','x2','x3','x4','x5','x6','x7','x8','x9','x10')
chr_x <- c('chr1','chr1','chr1','chr1','chr1','chr1','chr1','chr1','chrX','chrY')
start <- c(1,2,3,4,50,60,70,80,9,100)
stop <- c(10,20,30,40,500,600,700,800,95,1000)
x <- data.frame(ID_x,chr_x,start,stop)

> x
   ID_x chr_x start stop
1    x1  chr1     1   10
2    x2  chr1     2   20
3    x3  chr1     3   30
4    x4  chr1     4   40
5    x5  chr1    50  500
6    x6  chr1    60  600
7    x7  chr1    70  700
8    x8  chr1    80  800
9    x9  chrX     9   90
10  x10  chrY   100 1000

И второй:

ID_y <- c('y1','y2','y3','y4','y5','y6','y7','y8','y9','y10')
chr_y <- c('chr1','chr1','chr1','chr1','chr2','chr2','chr3','chr3','chrX','chrY')
pos_y <- c(8,9,15,31,41,2,81,8,91,8)
y <- data.frame(ID_y,chr_y,pos_y)

> y
   ID_y chr_y pos_y
1    y1  chr1     8
2    y2  chr1     9
3    y3  chr1    15
4    y4  chr1    31
5    y5  chr2    41
6    y6  chr2     2
7    y7  chr3    81
8    y8  chr3     8
9    y9  chrX    91
10  y10  chrY     8

Теперь я хотел бы отобразить строки от 2-го df (y) до первого df (x) на основе диапазона (start, stop) и chr. Я хотел бы перечислить все идентификаторы от y df (если они удовлетворяют критериям) для каждой строки df x. Там нет такого id_y, то нет. Итак, ожидаемый результат:

    ID_x chr_x start stop ID_y          pos_y
1    x1  chr1     1   10  y1,y2         8,9
2    x2  chr1     2   20  y1,y2,y3      8,9,15
3    x3  chr1     3   30  y1,y2,y3,y4   8,9,15,31
4    x4  chr1     4   40  y1,y2,y3,y4   8,9,15,31
5    x5  chr1    50  500  NA            NA
6    x6  chr1    60  600  NA            NA
7    x7  chr1    70  700  NA            NA
8    x8  chr1    80  800  NA            NA
9    x9  chrX     9   95  y9            91  
10  x10  chrY   100 1000  NA            NA

На первый взгляд, я подумал, что это кусок пирога, но когда я попытался решить эту проблему ... Я попробовал несколько подходов ... Вложенный apply() с ifelse()давал мне огромную матрицу с большим количеством NA ... Я нашел похожую проблему и решение здесь , но мой исходный набор данных огромен, df x имеет 134748 строк и df y имеет 865859 строк. У меня была ошибка выделения памяти, даже когда я пытался сделать это с одной хромосомой.

Не могли бы вы дать мне подсказку, как это сделать?

Спасибо, Адам

1 Ответ

2 голосов
/ 09 октября 2019

Для этого должно быть более эффективное решение с использованием data.table объединений, но вот один из способов сделать это с помощью dplyr. Сначала мы делаем left_join из x и y по "chr" столбцам, затем filter строк, которые находятся между start и stop, создаем разделенную запятыми строку для каждого chr_x, start и stop и, наконец, right_join с x, чтобы получить недостающий диапазон с NA.

library(dplyr)

left_join(x, y, by = c("chr_x" = "chr_y")) %>%
   filter(between(pos_y, start, stop)) %>%
   group_by(chr_x, start, stop) %>%
   summarise(ID_y = toString(ID_y), pos_y = toString(pos_y)) %>%
   right_join(x)


#   chr_x start  stop ID_y           pos_y        ID_x 
#   <chr> <dbl> <dbl> <chr>          <chr>        <fct>
# 1 chr1      1    10 y1, y2         8, 9         x1   
# 2 chr1      2    20 y1, y2, y3     8, 9, 15     x2   
# 3 chr1      3    30 y1, y2, y3     8, 9, 15     x3   
# 4 chr1      4    40 y1, y2, y3, y4 8, 9, 15, 31 x4   
# 5 chr1     50   500 NA             NA           x5   
# 6 chr1     60   600 NA             NA           x6   
# 7 chr1     70   700 NA             NA           x7   
# 8 chr1     80   800 NA             NA           x8   
# 9 chrX      9    95 y9             91           x9   
#10 chrY    100  1000 NA             NA           x10  
...