Сопоставить наборы данных по подмножеству условий - PullRequest
0 голосов
/ 30 января 2020

При сопоставлении 2 наборов данных возможно ли как-то указать соответствие так, чтобы наблюдение из первого набора данных сопоставлялось со вторым набором данных, если как минимум одно из условий встретились?

Допустим, у меня есть следующие 2 data.tables:

dt1<- data.table(c1=c(rep('a', 2), rep('b', 2), rep('c', 2)), 
                 c2=c('x','y','x','y','x','z'),
                 c3.min = c(rep(0,3), rep(-1,3)),
                 c3.max = c(rep(10,3), rep(11,3)),
                 x= (1:6))

dt2 <- data.table(c1=c(rep('a', 3), rep('b', 3), rep('c', 4)), 
                  c2=c(rep(c('x','y'), 5)),
                  c3=c(-1, 2, 0, 10, 11, -1, 3, 6, 3, 12),
                  y= (1:10))

У меня есть 3 условия, на основе которых я хочу сопоставить dt1 с dt2, а третье условие - это спектр. Если я просто сделаю нормальное слияние по этим 3 условиям, я получу:

> dt2[dt1, on=.(c1,
+               c2,
+               c3 <= c3.max,
+               c3 >= c3.min), nomatch=NA ]

   c1 c2 c3  y c3.1 x
1:  a  x 10  3    0 1
2:  a  y 10  2    0 2
3:  b  x 10 NA    0 3
4:  b  y 11  4   -1 4
5:  b  y 11  6   -1 4
6:  c  x 11  7   -1 5
7:  c  x 11  9   -1 5
8:  c  z 11 NA   -1 6

Как вы можете видеть, наблюдения из dt1 с x=3 и x=6 не совпадают. Моя главная задача - найти хотя бы одно совпадение для максимально возможного количества наблюдений в dt1, даже если мне придется ослабить некоторые условия. Поэтому я хочу знать, есть ли в любом случае соответствие, в котором dt1 совпадает с dt2 хотя бы в 1 из 3 условий?

Я мог бы написать al oop, но на самом деле мои 2 набора данных намного больше, чем это (первое имеет 10К наблюдений, а второе имеет 300К наблюдений), и у меня всего 4 условия, поэтому я ищу более эффективный способ.

Спасибо!

1 Ответ

2 голосов
/ 30 января 2020

Мой первый инстинкт такой проблемы - использовать пакет sqldf, поскольку нам нужно присоединиться, используя условия OR, а не AND.

library(sqldf)
names(dt1) <- c("c1", "c2", "c3_min", "c3_max", "x") # need to get rid of the "."

query1 <- "select * from dt1
left join dt2 
on (dt1.c1 = dt2.c1) or (dt1.c2 = dt2.c2) or (dt2.c3 between dt1.c3_min and dt1.c3_max)"

sqldf(query1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...