我正在改编示例shown here,在这里我想将一些测试结果与现有会话数据左连接,但是我知道测试可能是在会话之前或之后的三个小时进行的。由同一用户创建。
但是,尽管在user_id
选项中指定了by
列,但结果却重复了,并且值本身未添加到数据框中:
library(tidyverse)
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#>
#> date
library(fuzzyjoin)
sessions = tribble(
~user_id, ~session_id, ~session_created_at,
1, 1, "2019-01-01T15:30:00",
1, 2, "2019-01-02T00:00:30",
1, 3, "2019-01-04T12:30:00"
) %>%
mutate_at("session_created_at", as_datetime)
tests = tribble(
~user_id, ~test_id, ~test_created_at, ~test_value,
1, 7, "2019-01-01T15:28:00", "foo",
1, 8, "2019-01-01T23:59:30", "bar"
) %>%
mutate_at("test_created_at", as_datetime) %>%
mutate(
start = test_created_at + hours(3),
end = test_created_at - hours(3)
)
sessions %>%
fuzzy_left_join(
tests,
by = c(
"user_id" = "user_id",
"session_created_at" = "start",
"session_created_at" = "end"
),
match_fun = list(`==`, `>=`, `<=`)
)
#> # A tibble: 3 x 9
#> user_id.x session_id session_created_at user_id.y test_id
#> <dbl> <dbl> <dttm> <dbl> <dbl>
#> 1 1 1 2019-01-01 15:30:00 NA NA
#> 2 1 2 2019-01-02 00:00:30 NA NA
#> 3 1 3 2019-01-04 12:30:00 NA NA
#> # … with 4 more variables: test_created_at <dttm>, test_value <chr>,
#> # start <dttm>, end <dttm>
由reprex package(v0.2.1)于2019-05-17创建
为什么会这样,我该怎么做才能使其正常工作?
我应该在运行时添加它:
sessions %>%
left_join(tests, by = c("user_id" = "user_id"))
我得到了正确的列,但是当然没有正确的测试结果。当我运行此代码时,我得到了预期的结果,但效率似乎很低:
sessions %>%
left_join(tests) %>%
filter(test_created_at - hours(3) <= session_created_at) %>%
filter(test_created_at + hours(3) >= session_created_at)
答案 0 :(得分:0)
我了解到这是per design:
[…]设计假设是,在模糊联接期间,保持联接的两端都能够理解其匹配方式是有用的,并且没有特定的逻辑来处理折叠以使其相等。
在实施这种重复数据删除逻辑之前,您所能做的就是继续操作,并删除所有已知为重复的列,例如select(-ends_with(".y"))
并重命名以.x
结尾的域名,以使其后缀丢失。