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

Calculating date difference of subsequent rows based on each group in R

我有一个示例 table,看起来有点像这样:

| 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 和一些巨大的随机数。当 'Date' 字段的数据类型最初是 Posixct 时,我尝试了上面的代码。后来改成'Date'数据类型时,日期差异还是一样巨大的随机数。 此外,是否可以根据上面第二个 table 中提到的申请者和供应商 ID 对日期差异进行分组?

编辑: 我现在遇到了一个新的挑战。在问题集中,我需要过滤掉日期差异小于3天的值。让我们假设日期差异的 table 看起来像这样:

| 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。我有多次这样的事件。我该如何解决?

我认为您需要使用 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