如何根据 `dbplyr` 上的日期左连接数据框
How to left join on a dataframe based on dates on `dbplyr`
我正在尝试根据条件加入两个 data.frame
。考虑以下情况,我有 df_a
和 df_b
.
library(tidyverse)
# Dummy data A
df_a <- tibble(
id = c("a", "b", "c", "a"),
text = c("hi","why", "bye","cry"),
created_date = c(as.Date("2020-01-01"), as.Date("2020-02-02"), as.Date("2020-03-01"), as.Date("2020-04-04"))
)
# Dummy data B
df_b <- tibble(
id = c("a", "b", "c", "a"),
group = c("GROUP A","GROUP B","GROUP C", "GROUP C"),
start_date = c(as.Date("2020-01-01"), as.Date("2020-01-01"), as.Date("2020-01-01"), as.Date("2020-02-04"))
)
> df_a
# A tibble: 4 x 3
id text created_date
<chr> <chr> <date>
1 a hi 2020-01-01
2 b why 2020-02-02
3 c bye 2020-03-01
4 a cry 2020-04-04
> df_b
# A tibble: 4 x 3
id group start_date
<chr> <chr> <date>
1 a GROUP A 2020-01-01
2 b GROUP B 2020-01-01
3 c GROUP C 2020-01-01
4 a GROUP C 2020-02-04
# Current solution
d_current_sol <- df_a %>%
left_join(
df_b %>%
distinct(id, .keep_all = T), by = "id"
)
> d_current_sol
# A tibble: 4 x 5
id text created_date group start_date
<chr> <chr> <date> <chr> <date>
1 a hi 2020-01-01 GROUP A 2020-01-01
2 b why 2020-02-02 GROUP B 2020-01-01
3 c bye 2020-03-01 GROUP C 2020-01-01
4 a cry 2020-04-04 GROUP A 2020-01-01
# Desired solution
> d_desired
# A tibble: 4 x 5
id text created_date start_date group
<chr> <chr> <date> <date> <chr>
1 a hi 2020-01-01 2020-01-01 GROUP A
2 b why 2020-02-02 2020-01-01 GROUP B
3 c bye 2020-03-01 2020-01-01 GROUP C
4 a cry 2020-04-04 2020-02-04 GROUP C
如您在 df_b
中所见,id = a
的开始日期首先是 2020-01-01
,然后是 2020-02-04
。
我想要的是 df_a
中 2020-02-04
之后的任何行,它的关联组是 "GROUP C"
。这在最终数据框中得到了说明 d_desired
但是,对于我们将行与单个行项匹配的传统 left_join
,我们只会获得最早的条目 (d_current_sol
)。使用 map()
和使用 mutate()
的自定义函数很容易做到,但是,SQL 在翻译 dplyr
查询时不支持。
有谁知道通过 tidyverse
范式来做到这一点的方法吗?因为我将在 PostgreSQL 数据库上使用 dbplyr
到 运行。
这个?
df_a %>%
left_join(df_b, by = "id" ) %>%
filter( created_date >= start_date) %>%
group_by(id, created_date) %>%
top_n(1,start_date)
# A tibble: 4 x 5
# Groups: id, created_date [4]
id text created_date group start_date
<chr> <chr> <date> <chr> <date>
1 a hi 2020-01-01 GROUP A 2020-01-01
2 b why 2020-02-02 GROUP B 2020-01-01
3 c bye 2020-03-01 GROUP C 2020-01-01
4 a cry 2020-04-04 GROUP C 2020-02-04
我正在尝试根据条件加入两个 data.frame
。考虑以下情况,我有 df_a
和 df_b
.
library(tidyverse)
# Dummy data A
df_a <- tibble(
id = c("a", "b", "c", "a"),
text = c("hi","why", "bye","cry"),
created_date = c(as.Date("2020-01-01"), as.Date("2020-02-02"), as.Date("2020-03-01"), as.Date("2020-04-04"))
)
# Dummy data B
df_b <- tibble(
id = c("a", "b", "c", "a"),
group = c("GROUP A","GROUP B","GROUP C", "GROUP C"),
start_date = c(as.Date("2020-01-01"), as.Date("2020-01-01"), as.Date("2020-01-01"), as.Date("2020-02-04"))
)
> df_a
# A tibble: 4 x 3
id text created_date
<chr> <chr> <date>
1 a hi 2020-01-01
2 b why 2020-02-02
3 c bye 2020-03-01
4 a cry 2020-04-04
> df_b
# A tibble: 4 x 3
id group start_date
<chr> <chr> <date>
1 a GROUP A 2020-01-01
2 b GROUP B 2020-01-01
3 c GROUP C 2020-01-01
4 a GROUP C 2020-02-04
# Current solution
d_current_sol <- df_a %>%
left_join(
df_b %>%
distinct(id, .keep_all = T), by = "id"
)
> d_current_sol
# A tibble: 4 x 5
id text created_date group start_date
<chr> <chr> <date> <chr> <date>
1 a hi 2020-01-01 GROUP A 2020-01-01
2 b why 2020-02-02 GROUP B 2020-01-01
3 c bye 2020-03-01 GROUP C 2020-01-01
4 a cry 2020-04-04 GROUP A 2020-01-01
# Desired solution
> d_desired
# A tibble: 4 x 5
id text created_date start_date group
<chr> <chr> <date> <date> <chr>
1 a hi 2020-01-01 2020-01-01 GROUP A
2 b why 2020-02-02 2020-01-01 GROUP B
3 c bye 2020-03-01 2020-01-01 GROUP C
4 a cry 2020-04-04 2020-02-04 GROUP C
如您在 df_b
中所见,id = a
的开始日期首先是 2020-01-01
,然后是 2020-02-04
。
我想要的是 df_a
中 2020-02-04
之后的任何行,它的关联组是 "GROUP C"
。这在最终数据框中得到了说明 d_desired
但是,对于我们将行与单个行项匹配的传统 left_join
,我们只会获得最早的条目 (d_current_sol
)。使用 map()
和使用 mutate()
的自定义函数很容易做到,但是,SQL 在翻译 dplyr
查询时不支持。
有谁知道通过 tidyverse
范式来做到这一点的方法吗?因为我将在 PostgreSQL 数据库上使用 dbplyr
到 运行。
这个?
df_a %>%
left_join(df_b, by = "id" ) %>%
filter( created_date >= start_date) %>%
group_by(id, created_date) %>%
top_n(1,start_date)
# A tibble: 4 x 5
# Groups: id, created_date [4]
id text created_date group start_date
<chr> <chr> <date> <chr> <date>
1 a hi 2020-01-01 GROUP A 2020-01-01
2 b why 2020-02-02 GROUP B 2020-01-01
3 c bye 2020-03-01 GROUP C 2020-01-01
4 a cry 2020-04-04 GROUP C 2020-02-04