Слева объединить два фрейма данных R с условиями OR - PullRequest
1 голос
/ 18 октября 2019

Проблема

У меня есть два фрейма данных, которые я хочу объединить, используя условный оператор для трех нечисловых переменных. Вот псевдокодовая версия того, чего я хочу достичь.

Join DF1 and DF2 on DF1$A == DF2$A | DF1$A == DF2$B

Набор данных

Вот некоторый код для создания двух фреймов данных. variant_index - это фрейм данных, который будет использоваться для аннотирования input с использованием left_join:

library(dplyr)
options(stringsAsFactors = FALSE)

set.seed(5)
variant_index <- data.frame(
  rsid   = rep(sapply(1:5, function(x) paste0(c("rs", sample(0:9, 8, replace = TRUE)), collapse = "")), each = 2),
  chrom  = rep(sample(1:22, 5), each = 2),
  ref    = rep(sample(c("A", "T", "C", "G"), 5, replace = TRUE), each = 2),
  alt    = sample(c("A", "T", "C", "G"), 10, replace = TRUE),
  eaf    = runif(10),
  stringAsFactors = FALSE
)
variant_index[1, "alt"] <- "T"
variant_index[8, "alt"] <- "A"

input <- variant_index[seq(1, 10, 2), ] %>%
  select(rsid, chrom)
input$assessed <- c("G", "C", "T", "A", "T")

Что я пробовал

Я хотел бы выполнить left_join наinput для аннотирования с помощью столбца eaf из variant_index. Как видно из фрейма данных input, его столбец assessed может совпадать либо с input$ref, либо с input$alt. Столбцы rsid и chrom всегда будут совпадать.

Я знаю, что могу указать несколько столбцов в аргументе by left_join, но если я правильно понимаю, условие всегда будет

input$assessed == variant_index$ref & input$assessed == variant_index$alt

тогда как я хочу достичь

input$assessed == variant_index$ref | input$assessed == variant_index$alt

Возможное решение

Желаемый результат можно получить так:

input %>% 
  left_join(variant_index) %>% 
  filter(assessed == ref | assessed == alt)

Но это не такМне кажется, это не лучшее решение, так как я, возможно, генерирую двойные строки и хотел бы применить это объединение к фреймам данных, содержащим более 100 миллионов строк. Есть ли лучшее решение?

1 Ответ

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

Сложные объединения просты в SQL:

library(sqldf)

sqldf("select *
  from variant_index v
  join input i on i.assessed = v.ref or i.assessed = v.alt")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...