INNER JOIN возвращает нежелательные совпадения, SEMI JOIN возвращает ожидаемый результат, но пропущенные столбцы - PullRequest
0 голосов
/ 26 февраля 2019

Я уже некоторое время сталкиваюсь с этой проблемой, надеюсь, кто-нибудь поможет мне решить ее.

У меня есть два фрейма данных.

Первый содержит данные о вызовах каждого клиентаmade:

 Calls <- structure(list(OpenUser = c(55555, 33333, 22222, 44444, 22222, 
55555), OpenFirstName = c("Shir", "Yael", "Yair", "Roni", "Yair", 
"Shir"), OpenLastName = c("Shiran", "Eilon", "Yaron", "Ron", 
"Yaron", "Shiran"), CustomerID = c(836, 1070, 1390, 2970, 3646, 
3646), CRMEventStartDate = structure(c(1441065600, 1441065600, 
1431129600, 1435881600, 1417392000, 1441497600), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), NumOfOptions = c(1L, 1L, 2L, 3L, 3L, 
3L)), row.names = c(NA, -6L), class = c("grouped_df", "tbl_df", 
"tbl", "data.frame"), groups = structure(list(OpenUser = c(22222, 
22222, 33333, 44444, 55555, 55555), OpenFirstName = c("Yair", 
"Yair", "Yael", "Roni", "Shir", "Shir"), OpenLastName = c("Yaron", 
"Yaron", "Eilon", "Ron", "Shiran", "Shiran"), CustomerID = c(1390, 
3646, 1070, 2970, 836, 3646), .rows = list(3L, 5L, 2L, 4L, 1L, 
    6L)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", 
"data.frame"), .drop = TRUE))

Второй содержит данные о кампаниях, предлагаемых каждому клиенту, и ответ:

Response <- structure(list(CampaignStrategyID = c(512345, 512345, 512345, 
121212, 512345, 121212), CustomerID = c(836, 1070, 1390, 2970, 
3479, 3646), ResponseDate = structure(c(1441065600, 1441065600, 
1431129600, 1435881600, 1420502400, 1417392000), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), ResponseCode = c(1, 1, 1, 3, 2, 1)), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))

Я должен представить для каждый вызовклиент, что предложила фактическая кампания, и каков был их ответ.

INNER JOIN by CustomerID приводит к нежелательным совпадениям (предлагается не только кампания фактическая )

SEMI JOIN приводит к желаемым совпадениям (я думаю), но без нужных столбцов извторой фрейм данных (CampaignStrategyID & ResponseCode).Мне не удалось добавить эти столбцы после завершения SEMI JOIN.

Надеюсь, что кто-то может помочь.

Заранее спасибо.

1 Ответ

0 голосов
/ 26 февраля 2019

ОБНОВЛЕНИЕ 2019-03-03

Это обновлено с учетом новых предоставленных данных.Для устранения неполадок я сначала фильтрую данные примера в документированном случае проблемы, CustomerID 7033.

library(tidyverse)
library(lubridate)

Calls <- tibble(
  OpenUser = c(55555, 33333, 22222, 44444, 22222, 55555, 55555, 11111, 11111,
               44444, 44444, 11111, 44444, 44444, 33333, 44444, 11111, 33333,
               44444, 22222),
  OpenFirstName = c("Shir", "Yael", "Yair", "Roni", "Yair", "Shir", "Shir",
                    "Sigal", "Sigal", "Roni", "Roni", "Sigal", "Roni", "Roni",
                    "Yael", "Roni", "Sigal", "Yael", "Roni", "Yair"),
  OpenLastName = c("Shiran", "Eilon", "Yaron", "Ron", "Yaron", "Shiran",
                   "Shiran", "segal", "segal", "Ron", "Ron", "segal", "Ron",
                   "Ron", "Eilon", "Ron", "segal", "Eilon", "Ron", "Yaron"),
  CustomerID = c(836, 1070, 1390, 2970, 3646, 3646, 4542, 7033, 7033, 8838,
                 8838, 9040, 9040, 9973, 9973, 17472, 17472, 20409, 21626,
                 21632),
  CRMEventStartDate = ymd(c("2015-09-01", "2015-09-01", "2015-05-09",
                            "2015-07-03", "2014-12-01", "2015-09-06",
                            "2015-07-01", "2015-05-02", "2015-07-03",
                            "2015-06-04", "2015-07-08", "2015-03-01",
                            "2015-05-06", "2015-05-31", "2015-08-09",
                            "2015-04-01", "2015-08-02", "2015-04-01",
                            "2015-04-04", "2015-02-01")),
  NumOfOptions = c(1L, 1L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
                   3L, 3L, 3L, 3L, 3L)
)

Response <- tibble(
  CampaignStrategyID = c(512345, 512345, 512345, 121212, 512345, 121212, 516345,
                         516345, 121212, 512345, 121212, 512345, 121212, 512345,
                         516345, 512345, 512345, 512345, 121212, 516345, 512345,
                         512345, 516345, 512345, 516345, 512345, 512345, 121212,
                         121212, 512345, 121212, 512345, 516345, 516345, 512345,
                         121212, 121212, 121212, 512345, 512345, 121212, 516345,
                         121212, 121212, 516345, 516345, 512345, 121212, 121212,
                         121212),
  CustomerID = c(836, 1070, 1390, 2970, 3479, 3646, 3646, 4278, 4542, 7033,
                 7033, 8838, 8838, 9040, 9040, 9973, 9973, 17472, 17472, 20409,
                 21626, 21632, 22414, 24005, 24005, 26432, 26432, 28101, 28101,
                 31536, 31536, 31598, 31598, 32979, 32979, 35099, 37471, 37471,
                 38832, 38832, 39778, 40318, 40318, 46547, 48885, 48885, 49523,
                 49585, 55134, 56878),
  ResponseDate = ymd(c("2015-09-01", "2015-09-01", "2015-05-09", "2015-07-03",
                       "2015-01-06", "2014-12-01", "2015-09-06", "2015-01-02",
                       "2015-07-01", "2015-05-02", "2015-07-03", "2015-06-04",
                       "2015-07-08", "2015-03-01", "2015-05-06", "2015-05-31",
                       "2015-08-09", "2015-04-01", "2015-08-02", "2015-04-01",
                       "2015-04-04", "2015-02-01", "2015-01-31", "2015-05-08",
                       "2015-06-08", "2015-02-08", "2015-05-09", "2015-01-08",
                       "2015-08-04", "2015-06-06", "2015-06-09", "2015-05-05",
                       "2015-05-08", "2015-02-04", "2015-09-01", "2014-12-02",
                       "2014-12-04", "2015-07-02", "2015-05-08", "2015-09-01",
                       "2015-07-03", "2015-04-03", "2015-06-02", "2014-12-09",
                       "2015-01-03", "2015-09-09", "2015-06-04", "2015-08-06",
                       "2015-06-09", "2015-02-06")),
  ResponseCode = c(1, 1, 1, 3, 2, 1, 4, 2, 3, 1, 3, 2, 1, 3, 1, 1, 1, 4, 1, 4,
                   1, 2, 2, 1, 2, 2, 1, 2, 1, 2, 3, 1, 1, 2, 1, 1, 1, 3, 1, 1,
                   3, 1, 1, 2, 2, 4, 1, 1, 3, 2)
)

test_calls <- filter(Calls, CustomerID == 7033)
test_calls
#> # A tibble: 2 x 6
#>   OpenUser OpenFirstName OpenLastName CustomerID CRMEventStartDa…
#>      <dbl> <chr>         <chr>             <dbl> <date>          
#> 1    11111 Sigal         segal              7033 2015-05-02      
#> 2    11111 Sigal         segal              7033 2015-07-03      
#> # … with 1 more variable: NumOfOptions <int>

test_response <- filter(Response, CustomerID == 7033)
test_response
#> # A tibble: 2 x 4
#>   CampaignStrategyID CustomerID ResponseDate ResponseCode
#>                <dbl>      <dbl> <date>              <dbl>
#> 1             512345       7033 2015-05-02              1
#> 2             121212       7033 2015-07-03              3

Используя данные test_calls и test_response, я могу воспроизвести проблему:

inner_join(test_calls, test_response, by = "CustomerID")
#> # A tibble: 4 x 9
#>   OpenUser OpenFirstName OpenLastName CustomerID CRMEventStartDa…
#>      <dbl> <chr>         <chr>             <dbl> <date>          
#> 1    11111 Sigal         segal              7033 2015-05-02      
#> 2    11111 Sigal         segal              7033 2015-05-02      
#> 3    11111 Sigal         segal              7033 2015-07-03      
#> 4    11111 Sigal         segal              7033 2015-07-03      
#> # … with 4 more variables: NumOfOptions <int>, CampaignStrategyID <dbl>,
#> #   ResponseDate <date>, ResponseCode <dbl>

Теперь я вижу, что это происходит из-за того, как происходит сопоставление.Поскольку мы сопоставляем только CustomerID, все совпадающие строки в Calls, где есть соответствующая строка в Response, поэтому вы получаете все комбинации из 2 строк в Calls x 2 строки в Response(в результате получается 4 строки).

Чтобы исправить это, мы также можем сопоставить переменные даты (CRMEventStartDate и ResponseDate):

inner_join(test_calls, test_response,
           by = c("CustomerID", "CRMEventStartDate" = "ResponseDate"))
#> # A tibble: 2 x 8
#>   OpenUser OpenFirstName OpenLastName CustomerID CRMEventStartDa…
#>      <dbl> <chr>         <chr>             <dbl> <date>          
#> 1    11111 Sigal         segal              7033 2015-05-02      
#> 2    11111 Sigal         segal              7033 2015-07-03      
#> # … with 3 more variables: NumOfOptions <int>, CampaignStrategyID <dbl>,
#> #   ResponseCode <dbl>

Это приводит к ожидаемому2 строки с ответом, соответствующим CustomerID и дате события.


Исходное сообщение

Я думаю, что inner_join должно датьты чего хочешь.inner_join возвращает все столбцы из Calls и Response, но только строки, в которых есть совпадающая переменная (CustomerID) в обоих.Так, например, CustomerID 3749 отсутствует в данных Calls, поэтому для них нет строки в соединенных данных.И наоборот, CustomerID 3646 имеет две строки в данных Calls, поэтому они имеют 2 строки в соединенных данных.

library(tidyverse)

Calls <- structure(list(OpenUser = c(55555, 33333, 22222, 44444, 22222, 55555),
                        OpenFirstName = c("Shir", "Yael", "Yair", "Roni", "Yair", "Shir"),
                        OpenLastName = c("Shiran", "Eilon", "Yaron", "Ron", "Yaron", "Shiran"),
                        CustomerID = c(836, 1070, 1390, 2970, 3646, 3646),
                        CRMEventStartDate = structure(c(1441065600, 1441065600, 1431129600, 1435881600, 1417392000, 1441497600),
                                                      class = c("POSIXct", "POSIXt"), tzone = "UTC"),
                        NumOfOptions = c(1L, 1L, 2L, 3L, 3L, 3L)),
                   row.names = c(NA, -6L),
                   class = c("grouped_df", "tbl_df", "tbl", "data.frame"),
                   groups = structure(list(OpenUser = c(22222, 22222, 33333, 44444, 55555, 55555),
                                           OpenFirstName = c("Yair", "Yair", "Yael", "Roni", "Shir", "Shir"),
                                           OpenLastName = c("Yaron", "Yaron", "Eilon", "Ron", "Shiran", "Shiran"),
                                           CustomerID = c(1390, 3646, 1070, 2970, 836, 3646),
                                           .rows = list(3L, 5L, 2L, 4L, 1L, 6L)),
                                      row.names = c(NA, -6L),
                                      class = c("tbl_df", "tbl", "data.frame"),
                                      .drop = TRUE))


Response <- structure(list(CampaignStrategyID = c(512345, 512345, 512345, 121212, 512345, 121212),
                           CustomerID = c(836, 1070, 1390, 2970, 3479, 3646),
                           ResponseDate = structure(c(1441065600, 1441065600, 1431129600, 1435881600, 1420502400, 1417392000),
                                                    class = c("POSIXct", "POSIXt"), tzone = "UTC"),
                           ResponseCode = c(1, 1, 1, 3, 2, 1)),
                      row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

inner_join(Calls, Response)
#> Joining, by = "CustomerID"
#> # A tibble: 6 x 9
#> # Groups:   OpenUser, OpenFirstName, OpenLastName, CustomerID [6]
#>   OpenUser OpenFirstName OpenLastName CustomerID CRMEventStartDate  
#>      <dbl> <chr>         <chr>             <dbl> <dttm>             
#> 1    55555 Shir          Shiran              836 2015-09-01 00:00:00
#> 2    33333 Yael          Eilon              1070 2015-09-01 00:00:00
#> 3    22222 Yair          Yaron              1390 2015-05-09 00:00:00
#> 4    44444 Roni          Ron                2970 2015-07-03 00:00:00
#> 5    22222 Yair          Yaron              3646 2014-12-01 00:00:00
#> 6    55555 Shir          Shiran             3646 2015-09-06 00:00:00
#> # … with 4 more variables: NumOfOptions <int>, CampaignStrategyID <dbl>,
#> #   ResponseDate <dttm>, ResponseCode <dbl>

Создано в 2019-02-26 с помощью Представить пакет (v0.2.1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...