代码之家  ›  专栏  ›  技术社区  ›  MBB

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

  •  3
  • MBB  · 技术社区  · 9 年前

    df1 和 df2 dplyr

    df1 包含有关的一些信息 id , price 和 date 不是唯一的:给定 身份证件

    df2型 可以判断给定id的价格和/或日期值是否在

    然而,两者 df1 和 df2型 这可能有点棘手,因为您可以对给定的id进行多次修改。

    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
    

    1 回复  |  直到 9 年前
        1
  •  1
  •   Scarabee    9 年前

    首先,准备数据帧:

    # 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_join 然后 filter data.table 相反