我想知道是否有人知道dplyr
扩展包(dbplyr
和dtplyr
)是否允许在通常的dplyr工作流程中进行非相等连接?我很少需要data.table
,但是快速非对等连接是我总是需要setDT
的唯一时刻,然后执行连接,然后切换回as_tibble()
。我在github上的软件包中滚动了问题,但没有发现这是计划中的还是已经实现的。
非对等连接从1.1.0
开始通过join_by
函数可用。要创建非对等连接,您可以使用<
,>
,>=
,<=
或辅助between
,within
,overlaps
和nearest
。
library(dplyr)
#Example from https://github.com/tidyverse/dplyr/pull/5910.
set.seed(123)
dates <- as.Date("2019-01-01") + 0:4
needles <- tibble(dates = dates, x = sample(length(dates)))
set.seed(123)
lower <- as.Date("2019-01-01") + sample(6, 5, replace = TRUE)
upper <- lower + sample(2, 5, replace = TRUE)
haystack <- tibble(lower = lower, upper = upper, y = sample(length(lower)))
needles
#> # A tibble: 5 x 2
#> dates x
#> <date> <int>
#> 1 2019-01-01 3
#> 2 2019-01-02 2
#> 3 2019-01-03 5
#> 4 2019-01-04 4
#> 5 2019-01-05 1
haystack
#> # A tibble: 5 x 3
#> lower upper y
#> <date> <date> <int>
#> 1 2019-01-04 2019-01-06 1
#> 2 2019-01-07 2019-01-08 2
#> 3 2019-01-04 2019-01-05 3
#> 4 2019-01-03 2019-01-05 4
#> 5 2019-01-03 2019-01-05 5
# Non-equi join
# For each row in `needles`, find locations in `haystack` matching the condition
left_join(needles, haystack, by = join_by(dates >= lower, dates <= upper))
#> # A tibble: 12 x 5
#> dates x lower upper y
#> <date> <int> <date> <date> <int>
#> 1 2019-01-01 3 NA NA NA
#> 2 2019-01-02 2 NA NA NA
#> 3 2019-01-03 5 2019-01-03 2019-01-05 4
#> 4 2019-01-03 5 2019-01-03 2019-01-05 5
#> 5 2019-01-04 4 2019-01-04 2019-01-06 1
#> 6 2019-01-04 4 2019-01-04 2019-01-05 3
#> 7 2019-01-04 4 2019-01-03 2019-01-05 4
#> 8 2019-01-04 4 2019-01-03 2019-01-05 5
#> 9 2019-01-05 1 2019-01-04 2019-01-06 1
#> 10 2019-01-05 1 2019-01-04 2019-01-05 3
#> 11 2019-01-05 1 2019-01-03 2019-01-05 4
#> 12 2019-01-05 1 2019-01-03 2019-01-05 5
自1.4.0版本以来,dbplyr
中有了一个新的选项:sql_on
。引用Kirill m
dplyr有#2240,但这需要一段时间。对于数据库,我们已经有了一个解决方案。[/p].
library(dplyr)
library(dbplyr)
tbl1 <- memdb_frame(a = 1:3, b = 4:2)
tbl2 <- memdb_frame(c = 1:3, b = 2:0)
left_join(tbl1, tbl2, sql_on = "LHS.b < RHS.c")
Fordbplyr虽然SQL支持非对等连接,但我还没有找到与之等价的dplyr方法。我通常的工作方式与@Waldi发布的r-bloggers链接非常相似,即在相等条件下加入,然后在不相等条件下过滤。
例如:
output = join(df1, df2, by = c("df1_id" = "df2_id")) %>%
filter(df1_date <= df2_date)
转换成类似于以下语句的SQL:
SELECT *
FROM df1
JOIN df2
ON df1_id = df2_id
WHERE df1_date <= df2_date
这与
SELECT *
FROM df1
JOIN df2
ON df1_id = df2_id
AND df1_date <= df2_date