R из SAS PROC SQL Условное соединение - PullRequest
0 голосов
/ 09 апреля 2019

Я пытаюсь объединить две очень большие таблицы, основанные на условном выражении.Я хочу присоединить df2 к df1 в каждой группе (x), но включить только строки из df2, которые попадают в минимальное и максимальное значения в df2.

df1 <- data.frame(x = c(1,1,1,1,2,2,2,2,2,3), y = seq(1,10))
df2 <- data.frame(x2 = c(1,1,2,2,2), y_min = c(1, 1, 6, 6, 6), y_max = c(3,3,9,9,9), cat = c("A",'A','S','S','S'))

Результат, который я ищу, равен

df3 <- data.frame(x = c(1,1,1,1,2,2,2,2,2,3), y = seq(1,10), y_min = c(1,1,1,NA,NA,6,6,6,6,NA), y_max = c(3,3,3,NA,NA,9,9,9,9,NA), cat = c('A','A','A',NA,NA,'S','S','S','S',NA))

   x  y y_min y_max  cat
1  1  1     1     3    A
2  1  2     1     3    A
3  1  3     1     3    A
4  1  4    NA    NA <NA>
5  2  5    NA    NA <NA>
6  2  6     6     9    S
7  2  7     6     9    S
8  2  8     6     9    S
9  2  9     6     9    S
10 3 10    NA    NA <NA>

Первоначально он был написан в сценарии SAS PROC SQL, но у меня возникли проблемы с его преобразованием в R. Оператор SQL PROC выглядел примерно так ...

PROC SQL;
SELECT a.*, b.*
FROM tbl1 a
LEFT JOIN tbl2 b
   on (a.col1 - b.col1) >= 0 and (a.col1 - b.col2) <= 0
     and a.id = b.id

Я пыталсяиспользую base :: & data.table :: merge, но мне не повезло.Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 09 апреля 2019

Вы можете использовать пакет sqldf, чтобы использовать SQL код для R объектов. В качестве дополнительного примечания, ваши имена SAS отличались от имен, которые вы использовали в R, для дальнейшего использования убедитесь, что они одинаковые, чтобы люди могли воспроизводить их.

library(sqldf)
df1 <- data.frame(x = c(1,1,1,1,2,2,2,2,2,3), y = seq(1,10))
df2 <- data.frame(x2 = c(1,1,2,2,2), y_min = c(1, 1, 6, 6, 6), y_max = c(3,3,9,9,9), cat = c("A",'A','S','S','S'))

sqldf('SELECT a.*, b.*
FROM df1 a
LEFT JOIN df2 b
   on (a.y - b.y_min) >= 0 and (a.y- b.y_max) <= 0
     and a.x = b.x2')
1 голос
/ 09 апреля 2019

Использование data.table:

library(data.table)

setDT(df1)
setDT(df2)

unique(df2)[df1,
            .(x = i.x, y = i.y, y_min = x.y_min, y_max = x.y_max, cat = x.cat),
            on = c("x2 == x", "y_min <= y", "y_max >= y")]

    x  y y_min y_max  cat
 1: 1  1     1     3    A
 2: 1  2     1     3    A
 3: 1  3     1     3    A
 4: 1  4    NA    NA <NA>
 5: 2  5    NA    NA <NA>
 6: 2  6     6     9    S
 7: 2  7     6     9    S
 8: 2  8     6     9    S
 9: 2  9     6     9    S
10: 3 10    NA    NA <NA>

Просто примечание - в df2 были повторяющиеся строки, в результате чего простое левое объединение дало больше строк, чем вы указали в df3, следовательно, вызов unique().

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