根据两列进行分组,然后创建一个新列以根据各组计算时差

时间:2019-08-07 18:22:23

标签: r date group-by dplyr mutate

我有一个数据集,其中包括供应商ID,买方ID和交易日期。这是一个示例数据集:

df= data.frame(supplier_id= c("176", "345", "343", "766", "766", "766", "278", "341", "341","890","789","687","787","787"), buyer= c("wang","cheng","li","cheng","cheng",
"cheng","li","wang","wang","Echo","Kelly","Kelly","cheng","cheng"), date=c("2/20/2018","2/26/2018",
"1/2/2019","4/10/2018","4/10/2018","4/10/2018","4/18/2018","4/18/2018","1/5/2019","2/23/2018","2/23/2018","6/29/2017","6/20/2017","5/11/2017"))

df$date=as.Date(df$date, format="%m/%d/%y")

此问题分为两部分。这个问题的第一部分是按以下方式排列数据集:我们将相同的买方和相同的供应商分组在一起,并按照买方名称的升序排列,同时分别按每个组的日期升序排列。数据将如下所示:

| supplier_id | Buyer |      date |
|-------------|:-----:|----------:|
| 345         | cheng | 2/26/2018 |
| 766         | cheng | 4/10/2018 |
| 766         | cheng | 4/10/2018 |
| 766         | cheng | 4/10/2018 |
| 787         | cheng | 4/18/2018 |
| 787         | cheng | 4/18/2018 |
|             |       |           |
| 890         | Echo  | 6/29/2017 |
|             |       |           |
| 789         | Kelly | 5/11/2017 |
| 687         | Kelly | 6/20/2017 |
|             |       |           |
| 343         | li    | 1/2/2019  |
| 278         | li    | 1/5/2019  |
|             |       |           |
| 176         | wang  | 2/20/2018 |
| 341         | wang  | 2/23/2018 |
| 341         | wang  | 2/23/2018 |

问题的第二部分是确定5天之内发生的交易。因此,我们将创建一个新列,然后将计算日期差,然后使用新列的数据将是:

| supplier_id | Buyer |      date | date_diff |
|-------------|:-----:|----------:|-----------|
| 345         | cheng | 2/26/2018 | 43        |
| 766         | cheng | 4/10/2018 | 0         |
| 766         | cheng | 4/10/2018 | 0         |
| 766         | cheng | 4/10/2018 | 8         |
| 787         | cheng | 4/18/2018 | 0         |
| 787         | cheng | 4/18/2018 | NA        |
|             |       |           |           |
| 890         | Echo  | 6/29/2017 | NA        |
|             |       |           |           |
| 789         | Kelly | 5/11/2017 | 40        |
| 687         | Kelly | 6/20/2017 | NA        |
|             |       |           |           |
| 343         | li    | 1/2/2019  | 3         |
| 278         | li    | 1/5/2019  | NA        |
|             |       |           |           |
| 176         | wang  | 2/20/2018 | 3         |
| 341         | wang  | 2/23/2018 | 0         |
| 341         | wang  | 2/23/2018 | NA        |

然后,我需要选择所有交易间隔为5天的日期。因此,那将是date_diff <= 5,但是,如果按照我的逻辑,它将排除日期“ 4/10/2018”(第4条记录),因为4/10/2018与4 /之间的日期差18/2018是8。但是,在4/10/2018发生了3笔交易,所以我有兴趣获取所有3个日期。我首先想到使用“ elseif”,但这并不能消除我保留日期“ 4/10/2018”的问题,并且我的原始数据集中有很多这样的情况。我对这种方法一无所知。

我尝试使用group_by和mutate将买方和Supplier_id分组,然后创建一个新列以计算日期差,但是,我的代码未提供所需的输出。

df1=df %>% group_by(buyer, supplier_id) %>% 
  mutate(diffdate= difftime(date,lag(date,1),units='days')) 

我也可以使用“排列”功能,但这只会按升序排列数据集,而不会按买家和Supplier_id对数据进行分组以计算日期差。

我的预期输出应该是:

| supplier_id | Buyer | date      |
|-------------|-------|-----------|
| 766         | cheng | 4/10/2018 |
| 766         | cheng | 4/10/2018 |
| 766         | cheng | 4/10/2018 |
| 787         | cheng | 4/18/2018 |
| 787         | cheng | 4/18/2018 |
|             |       |           |
| 343         | li    | 1/2/2019  |
| 278         | li    | 1/5/2019  |
|             |       |           |
| 176         | wang  | 2/20/2018 |
| 341         | wang  | 2/23/2018 |
| 341         | wang  | 2/23/2018 |

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

这是一个可能的解决方案。对于每个唯一的买方-日期组合,您可以使用tidyr::complete创建可以包含的日期范围(+/- 5天)。然后加入原始数据并计算摘要统计信息。我添加了“值”列来说明这一点。

df$value <- runif(nrow(df))

df1 <- df %>% arrange(buyer,date) %>% distinct(buyer,date) %>% 
  mutate(date.orig=date) %>% 
  group_by(buyer,date,date.orig) %>% 
  complete(date=seq(from=(date-5),to=(date+5),by=1))

df1 %>% left_join(df) %>% group_by(buyer,date.orig) %>% 
  summarise(s=sum(value,na.rm=1),n=sum(!is.na(value)))

不幸的是,您的示例数据并不能真正为该解决方案提供良好的测试,因为只有Cheng一天有多笔交易,没有买家在5天之内有多笔交易。