使用R的模糊联接产生重复的列,并且没有联接值

时间:2019-05-17 10:29:47

标签: r dplyr

我正在改编示例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)

1 个答案:

答案 0 :(得分:0)

我了解到这是per design

  

[…]设计假设是,在模糊联接期间,保持联接的两端都能够理解其匹配方式是有用的,并且没有特定的逻辑来处理折叠以使其相等。

在实施这种重复数据删除逻辑之前,您所能做的就是继续操作,并删除所有已知为重复的列,例如select(-ends_with(".y"))并重命名以.x结尾的域名,以使其后缀丢失。