У меня есть два фрейма данных, к которым я бы хотел присоединиться по датам

df1 <-
  data.frame(
    day = seq(ymd("2020-01-01"), ymd("2020-01-14"), by = "1 day"),
    key = rep(c("green", "blue"), 7),
    value_x = sample(1:100, 14)
  ) %>% 
    as_tibble()

df2 <-
  data.frame(
    day = seq(ymd("2020-01-01"), ymd("2020-01-12"), by = "3 days"),
    key = rep(c("green", "blue"), 2),
    value_y = c(2, 4, 6, 8)
  ) %>% 
  as_tibble()

Я хочу, чтобы результат был таким

# A tibble: 14 x 3
   day        key   value_x   value_y
   <date>     <fct>   <int>     <int>
 1 2020-01-01 green      91         2
 2 2020-01-02 blue       28        NA
 3 2020-01-03 green      75         2
 4 2020-01-04 blue       14         4
 5 2020-01-05 green       3         2
 6 2020-01-06 blue       27         4
 7 2020-01-07 green      15         6
 8 2020-01-08 blue        7         4
 9 2020-01-09 green       1         6
10 2020-01-10 blue       10         8
11 2020-01-11 green       9         6
12 2020-01-12 blue       76         8
13 2020-01-13 green      31         6
14 2020-01-14 blue       62         8

Я пробовал делать этот код

merge(df1, df2, by = c("day", "key"), all.x = TRUE)

Я хочу, чтобы день в левой таблице присоединился к самому последнему дню в таблице Y, имеющему значение. Если значение отсутствует, оно должно быть NA.

Редактировать --

Не все даты в df2 появятся в df1, хотя у них есть общий идентификатор. Это пример-

df1 

day           id       key  
1 2020-01-08    A    green
2 2020-01-10    A    green
3 2020-02-24    A    blue 
4 2020-03-24    A    green
   
df2 

day            id   value 
1 2020-01-03    A       2
2 2020-01-07    A       4
3 2020-01-22    A       4
4 2020-03-24    A       6   

desired output

day           id       key    value
1 2020-01-08    A    green        4   
2 2020-01-10    A    green        4
3 2020-02-24    A    blue         4
4 2020-03-24    A    green        6 
1
Cauder 7 Сен 2020 в 03:38

1 ответ

Лучший ответ

После слияния вы можете arrange данные на основе key и day и fill с самым последним значением, отличным от NA.

library(dplyr)

merge(df1, df2, by = c('day', 'key'), all.x = TRUE) %>%
  arrange(key, day) %>%
  group_by(key) %>%
  tidyr::fill(value_y) %>%
  arrange(day)

#          day   key value_x value_y
#1  2020-01-01 green      40       2
#2  2020-01-02  blue      45      NA
#3  2020-01-03 green      54       2
#4  2020-01-04  blue      11       4
#5  2020-01-05 green      12       2
#6  2020-01-06  blue       7       4
#7  2020-01-07 green      72       6
#8  2020-01-08  blue      76       4
#9  2020-01-09 green      52       6
#10 2020-01-10  blue      32       8
#11 2020-01-11 green      69       6
#12 2020-01-12  blue      10       8
#13 2020-01-13 green      63       6
#14 2020-01-14  blue      84       8

Для обновленных данных вы можете использовать следующее:

df1 %>%
  left_join(df2, by = 'id') %>%
  mutate(diff = day.x - day.y) %>%
  group_by(id, key, day.x) %>%
  filter(diff == min(diff[diff >= 0])) %>%
  arrange(day.x) %>%
  select(day = day.x, id, key, value)

#   day        id    key   value
#  <date>     <chr> <chr> <int>
#1 2020-01-08 A     green     4
#2 2020-01-10 A     green     4
#3 2020-02-24 A     blue      4
#4 2020-03-24 A     green     6
3
Ronak Shah 7 Сен 2020 в 04:01