根据R中的每个组计算后续行的日期差

时间:2019-07-16 19:17:45

标签: r datetime group-by grouping datediff

我有一个样本表,看起来像这样:

| Date       | Vendor_Id | Requisitioner | Amount |
|------------|:---------:|--------------:|--------|
| 1/17/2019  |     98    |          John | 2405   |
| 4/30/2019  |    1320   |          Dave | 1420   |
| 11/29/2018 |    3887   |       Michele | 596    |
| 11/29/2018 | 3887      | Michele       | 960    |
| 11/29/2018 | 3887      | Michele       | 1158   |
| 9/21/2018  | 4919      | James         | 857    |
| 10/25/2018 | 4919      | Paul          | 1162   |
| 10/26/2018 | 4919      | Echo          | 726    |
| 10/26/2018 | 4919      | Echo          | 726    |
| 10/29/2018 | 4919      | Andrew        | 532    |
| 10/29/2018 | 4919      | Andrew        | 532    |
| 11/12/2018 | 4919      | Carlos        | 954    |
| 5/21/2018  | 2111      | June          | 3580   |
| 5/23/2018  | 7420      | Justin        | 224    |
| 5/24/2018  | 1187      | Sylvia        | 3442   |
| 5/25/2018  | 1187      | Sylvia        | 4167   |
| 5/30/2018  | 3456      | Ama           | 4580   |

基于每个请购者和供应商ID,我需要找到日期的差异,使得它应该像这样:

| Date       | Vendor_Id | Requisitioner | Amount | Date_Diff |
|------------|:---------:|--------------:|--------|-----------|
| 1/17/2019  |     98    |          John | 2405   | NA        |
| 4/30/2019  |    1320   |          Dave | 1420   | 103       |
| 11/29/2018 |    3887   |       Michele | 596    | NA        |
| 11/29/2018 | 3887      | Michele       | 960    | 0         |
| 11/29/2018 | 3887      | Michele       | 1158   | 0         |
| 9/21/2018  | 4919      | James         | 857    | NA        |
| 10/25/2018 | 4919      | Paul          | 1162   | NA        |
| 10/26/2018 | 4919      | Paul          | 726    | 1         |
| 10/26/2018 | 4919      | Paul          | 726    | 0         |
| 10/29/2018 | 4919      | Paul          | 532    | 3         |
| 10/29/2018 | 4919      | Paul          | 532    | 0         |
| 11/12/2018 | 4917      | Carlos        | 954    | NA        |
| 5/21/2018  | 2111      | Justin        | 3580   | NA        |
| 5/23/2018  | 7420      | Justin        | 224    | 2         |
| 5/24/2018  | 1187      | Sylvia        | 3442   | NA        |
| 5/25/2018  | 1187      | Sylvia        | 4167   | 1         |
| 5/30/2018  | 3456      | Ama           | 4580   | NA        |

现在,如果每个请购者和供应商ID之间的日期差为<= 3天,且金额之和大于5000,则需要创建一个子集。最终输出应该是这样的:

| Date      | Vendor_Id | Requisitioner | Amount | Date_Diff |
|-----------|:---------:|--------------:|--------|-----------|
| 5/24/2018 |    1187   |        Sylvia | 3442   | NA        |
| 5/25/2018 |    1187   |        Sylvia | 4167   | 1         |

最初,当我尝试使用日期差时,我使用了以下代码:

df=df %>% mutate(diffdate= difftime(Date,lag(Date,1))) 

但是,差异是没有意义的,因为它们是诸如86400的巨大数字和一些巨大的随机数字。当“日期”字段的数据类型最初为Posixct时,我尝试了上面的代码。后来,当我将其更改为“日期”数据类型时,日期差异仍然是相同的巨大随机数。 另外,是否可以如上表2中所述根据申请者和供应商ID对日期差异进行分组?

编辑: 我现在正面临一个新的挑战。在问题集中,我需要过滤出日期差小于3天的值。让我们假设具有日期差的表看起来像这样:

| MasterCalendarDate | Vendor_Id | Requisitioner | Amount | diffdate |
|--------------------|:---------:|--------------:|--------|----------|
| 1/17/2019          |     98    |          John | 2405   | #N/A     |
| 4/30/2019          |    1320   |          Dave | 1420   | 103      |
| 11/29/2018         | 3887      | Michele       | 596    | #N/A     |
| 11/29/2018         | 3887      | Michele       | 960    | 0        |
| 11/29/2018         | 3887      | Michele       | 1158   | 0        |
| 9/21/2018          | 4919      | Paul          | 857    | #N/A     |
| 10/25/2018         | 4919      | Paul          | 1162   | 34       |
| 10/26/2018         | 4919      | Paul          | 726    | 1        |
| 10/26/2018         | 4919      | Paul          | 726    | 0        |

当我们查看申购人'Paul'时,9/21/2018和10/25/2018之间的日期差是34,而10/25/2018和10/26/2018之间的日期差是1天。但是,当我为日期差异<= 3天筛选数据时,由于存在34天的差异,我错过了10/25/2018。我有多次这样的事件。我该如何解决?

1 个答案:

答案 0 :(得分:1)

我认为您需要使用as.Date()转换日期变量,然后才能使用difftime()计算滞后时间差。

# create toy data frame
df <- data.frame(date=as.Date(paste(sample(2018:2019,100,T),
                            sample(1:12,100,T),
                            sample(1:28,100,T),sep = '-')),
                 req=sample(letters[1:10],100,T),
                 amount=sample(100:10000,100,T))

# compute lagged time difference in days -- diff output is numeric
df %>% arrange(req,date) %>% group_by(req) %>% 
  mutate(diff=as.numeric(difftime(date,lag(date),units='days')))

# as above plus filtering based on time difference and amount
df %>% arrange(req,date) %>% group_by(req) %>% 
  mutate(diff=as.numeric(difftime(date,lag(date),units='days'))) %>% 
  filter(diff<10 | is.na(diff), amount>5000)

# A tibble: 8 x 4
# Groups:   req [7]
  date       req   amount  diff
  <date>     <fct>  <int> <dbl>
1 2018-05-13 a       9062    NA
2 2019-05-07 b       9946     2
3 2018-02-03 e       5697    NA
4 2018-03-12 g       7093    NA
5 2019-05-16 g       5631     3
6 2018-03-06 h       7114     6
7 2018-08-12 i       5151     6
8 2018-04-03 j       7738     8