Условный cbind() для дат

Предположим, у нас есть 2 кадра данных по 2 столбца и 6 строк в каждом, и мы хотим связать оба только тогда, когда дата слева (слева) старше, чем дата справа (справа), в то же время убедившись, что каждая строка не имеет даты дубликаты (как слева, так и справа): например..

x = cbind(data.frame(lhs_date = seq(Sys.Date()-5, Sys.Date(),2)), letter=c("A","B","C","D","E","F") )
Y = cbind(data.frame(rhs_date = seq(Sys.Date()-5, Sys.Date(),1)), letter=c("X","Y","Y","X","J","J") )

Как мы можем cbind или левое соединение x с y только тогда, когда дата слева ‹ дата справа, сохраняя уникальность каждой строки?


person AlGrasso    schedule 26.11.2019    source источник
comment
Взгляните на github.com/dgrtwo/fuzzyjoin.   -  person agila    schedule 26.11.2019


Ответы (2)


Я не уверен, что понял ваш вопрос, но вы ищете что-то подобное?

# packages
library(fuzzyjoin)

# data
x <- data.frame(lhs_date = seq(Sys.Date() - 5, Sys.Date(), 2), letter = c("A","B","C","D","E","F"))
y <- data.frame(rhs_date = seq(Sys.Date() - 5, Sys.Date(), 1), letter = c("X","Y","Y","X","J","J"))

# left join
fuzzy_left_join(
  x = x, 
  y = y, 
  by = c("lhs_date" = "rhs_date"),
  match_fun = list(`<`)
)
#>      lhs_date letter.x   rhs_date letter.y
#> 1  2019-11-21        A 2019-11-22        Y
#> 2  2019-11-21        A 2019-11-23        Y
#> 3  2019-11-21        A 2019-11-24        X
#> 4  2019-11-21        A 2019-11-25        J
#> 5  2019-11-21        A 2019-11-26        J
#> 6  2019-11-23        B 2019-11-24        X
#> 7  2019-11-23        B 2019-11-25        J
#> 8  2019-11-23        B 2019-11-26        J
#> 9  2019-11-25        C 2019-11-26        J
#> 10 2019-11-21        D 2019-11-22        Y
#> 11 2019-11-21        D 2019-11-23        Y
#> 12 2019-11-21        D 2019-11-24        X
#> 13 2019-11-21        D 2019-11-25        J
#> 14 2019-11-21        D 2019-11-26        J
#> 15 2019-11-23        E 2019-11-24        X
#> 16 2019-11-23        E 2019-11-25        J
#> 17 2019-11-23        E 2019-11-26        J
#> 18 2019-11-25        F 2019-11-26        J

Создана 26 ноября 2019 г. с помощью пакета reprex (v0.3.0)

person agila    schedule 26.11.2019
comment
Спасибо, это было близко, но не то, что я имел в виду. Каждая строка слева должна быть уникальной, как и каждая строка справа. Это означает, что из 6 строк мы можем получить меньше строк или вообще не получить их вовсе, если какая-либо строка в левой части старше, чем в правой. По сути, это перекрестное соединение между каждой строкой левого и каждой строки правого, возвращающее уникальные значения без дубликатов. В этом случае это будет примерно так: 2019-11-21 A 2019-11-22 Y 2019-11-23 B 2019-11-24 X 2019-11-25 C 2019-11-26 J ...и т.д. . - person AlGrasso; 26.11.2019
comment
@AlGrasso, я все еще не уверен, что понимаю ваш комментарий, так как я не получаю тот же результат, который вы описываете. Можете ли вы проверить, работает ли bind_cols(x, y) %>% filter(lhs_date >= rhs_date) для вашего примера? Вам нужно загрузить пакет dplyr и определить x и y, как я сделал в этом ответе. - person agila; 27.11.2019

Решение, которое я нашел, основано на первоначальном вводе agila: после нечеткого соединения dplyr pipe оператор может сделать все остальное:

x <- data.frame(lhs_date = seq(Sys.Date() - 5, Sys.Date(), 2), letter = c("A","B","C","D","E","F"))
y <- data.frame(rhs_date = seq(Sys.Date() - 5, Sys.Date(), 1), letter = c("X","Y","Y","X","J","J"))

z= fuzzy_left_join(
  x = x, 
  y = y, 
  by = c("lhs_date" = "rhs_date"),
  match_fun = list(`<`)
)

z %>%
  group_by(lhs_date) %>%
  mutate(flag = row_number()) %>%
  filter(flag ==1)

Я мог легко воспроизвести в SQL, но боролся с R. Спасибо @Agila. Несмотря на то, что ваш ответ неполный, он указал правильное направление и в значительной степени

person AlGrasso    schedule 27.11.2019