tidyverse中的非对等连接

uajslkp6  于 2023-02-01  发布在  其他
关注(0)|答案(3)|浏览(147)

我想知道是否有人知道dplyr扩展包(dbplyrdtplyr)允许在通常的dplyr工作流程中使用非等长连接吗?我很少需要data.table,但是快速非等长连接是我唯一需要使用setDT的时候,然后执行join,然后切换回as_tibble()。我浏览了github上的包中的问题,但没有发现这是计划中的还是已经实现的。

llycmphe

llycmphe1#

1.1.0开始,可以通过函数join_by使用非等长联接。要创建非等长联接,可以使用<>>=<=或助手betweenwithinoverlapsnearest

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
mcdcgff0

mcdcgff02#

从1.4.0版本开始,dbplyr中有了一个新的选项:sql_on .引用基里尔·穆勒:
dplyr有#2240,但是需要一段时间。对于数据库,我们已经有了一个解决方案[即通用SQL连接]。

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")
wbgh16ku

wbgh16ku3#

对于dbplyr:虽然SQL支持non-equi连接,但我还没有找到一种等效的dplyr方法,我通常的工作与@Waldi发布的r-blogger链接非常相似,即根据相等条件进行连接,然后根据不相等条件进行过滤。
例如:

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

相关问题