尝试合并两个具有特定条件的数据帧和 R 中行的间隙

Trying to merge two dataframes with specific conditions and gap in the rows in R

我有两个数据帧(df1df2)。我正在与 dplyr 合作来处理我的数据。但是,我很难找到以下结果:

df1 包含一些关于 idpricedate 的信息(id 不是唯一的:给定的 id 可以决定几个价格)

df2 可以判断对于给定的 id,df1

中的价格 and/or 日期的值是否已被修改

我想知道价格and/or日期是否有修改,如果是的话,我想把这个新值作为price/date

但是,df1df2 都可能有点棘手,因为您可以对给定的 ID 进行多次修改。

更具体地说,对于给定的价格修改(如果存在,否则我取df1中给出的价格),我想将其与日期的最后修改(如果存在,否则我取df1)中给出的日期只要是<= df1$date + 30

总结一下,这里有一个例子:

df1 <- data.frame(
       Id = c(1,1,2),
       price = c(1000,2000,1000),
       date = c("2016-01-01","2016-09-01","2016-01-01")
    )
df1
  Id price       date
  1  1000   2016-01-01
  1  2000   2016-09-01
  2  1000   2016-01-01

df2 如下:

df2 <- data.frame(
   Id = c(1,1,1,1,1,2,2),
   price = c(1500,NA,2000,NA,3000,NA,NA),
   date = c(NA, "2016-01-03", "2016-01-05", "2016-09-02","2016-09-03","2016-01-03","2016-01-05")
)

df2
  Id price       date
  1  1500       <NA>
  1    NA   2016-01-03
  1  2000   2016-01-05
  1    NA   2016-09-02
  1  3000   2016-09-03
  2    NA   2016-01-03
  2    NA   2016-01-05

我希望得到与此类似的结果:

  Id initial_price  initial_date   is_modification_price  is_modification_date true_price    true_date

  1   1000          2016-01-01          TRUE                     TRUE             2000       2016-01-05
  1   2000          2016-09-01          TRUE                     TRUE             3000       2016-09-03
  2   1000          2016-01-01          FALSE                    TRUE             1000       2016-01-05

希望我说得够清楚

有没有人知道如何实现这个;甚至完全不同的方法?

首先,准备您的数据框:

# fix type
df1 <- mutate(df1, date = as.Date(date))

# fill NAs in df2
df2 <- df2 %>%
  mutate(date = as.Date(date)) %>%
  group_by(Id) %>%
  tidyr::fill(price, date) %>%
  ungroup

# fill remaining NAs with default values taken from df1
default_values <- df1 %>%
  group_by(Id) %>%
  slice(1) %>%
  rename(price0 = price, date0 = date) %>%
  ungroup

df2 <- df2 %>%
  left_join(default_values, by = "Id") %>%
  mutate(price = if_else(is.na(price), price0, price),
         date = if_else(is.na(date), date0, date)) %>%
  select(Id, price, date)

然后加入:

df1 %>%
  left_join(df2, by = "Id") %>%
  filter(date.y <= date.x + 30) %>%
  group_by(Id, price.x, date.x) %>%
  arrange(date.y) %>%
  slice(n()) %>%
  ungroup %>%
  rename(initial_price = price.x, initial_date = date.x,
         true_price = price.y, true_date = date.y) %>%
  mutate(is_modification_price = (initial_price != true_price),
         is_modification_date = (initial_date != true_date))
# # A tibble: 3 x 7
#      Id initial_price initial_date true_price  true_date is_modification_price is_modification_date
#   <dbl>         <dbl>       <date>      <dbl>     <date>                 <lgl>                <lgl>
# 1     1          1000   2016-01-01       2000 2016-01-05                  TRUE                 TRUE
# 2     1          2000   2016-09-01       3000 2016-09-03                  TRUE                 TRUE
# 3     2          1000   2016-01-01       1000 2016-01-05                 FALSE                 TRUE

请注意,最后一步中的 left_joinfilter 可能会占用太多内存。如果是这种情况,请改用 data.table 中的非等连接功能。