首页 > 解决方案 > 每组内移位的不同 n(偏移量)

问题描述

想计算动作 A 和动作 X 之间的经过时间。其他动作(B、C 等)有不同的逻辑,但它们涉及到类似的时间差。

有没有办法在班次中使用计算值进行偏移?我过去曾使用 shift 来进行固定偏移,例如使用 lag 在组内返回 12 行,但不知道如何在 shift 中合并条件偏移

这是一个虚构的例子:

x <- data.table(Case = c(1,1,1,1,2,2,2,3,3,3,3,3), Action = c("A","B","C","X","A","X","X","A","C","X","A","X"), ActionTime = parse_date_time(c("1/23/2020 12:55","1/26/20 3:23","1/28/2020 4:23","4/16/2020 17:50","1/25/2020 23:04","2/12/2020 17:50","2/13/2020 17:50","1/26/2020 3:23","2/18/2020 21:23","2/18/2020 21:27","3/15/2020 3:23","3/18/2020 21:27"), orders=c('mdy HM')))
setkeyv(x, c("Case", "ActionTime"))

    > x
    Case Action          ActionTime
 1:    1      A 2020-01-23 12:55:00
 2:    1      B 2020-01-26 03:23:00
 3:    1      C 2020-01-28 04:23:00
 4:    1      X 2020-04-16 17:50:00
 5:    2      A 2020-01-25 23:04:00
 6:    2      X 2020-02-12 17:50:00
 7:    2      X 2020-02-13 17:50:00
 8:    3      A 2020-01-26 03:23:00
 9:    3      C 2020-02-18 21:23:00
10:    3      X 2020-02-18 21:27:00
11:    3      A 2020-03-15 03:23:00
12:    3      X 2020-03-18 21:27:00

案例 1 是简单的案例,案例 2 是动作 X 多次显示但我需要时间的最小值和第 3 组,其中 A 和 X 在同一案例中多次显示。

我希望获得 XTime = 在案例中出现 A 后最近的 X 的时间戳:

    Case Action          ActionTime          XTime
 1:    1      A 2020-01-23 12:55:00          2020-04-16 17:50:00
 2:    1      B 2020-01-26 03:23:00
 3:    1      C 2020-01-28 04:23:00
 4:    1      X 2020-04-16 17:50:00
 5:    2      A 2020-01-25 23:04:00          2020-02-12 17:50:00
 6:    2      X 2020-02-12 17:50:00
 7:    2      X 2020-02-13 17:50:00
 8:    3      A 2020-01-26 03:23:00          2020-02-18 21:27:00
 9:    3      C 2020-02-18 21:23:00
10:    3      X 2020-02-18 21:27:00
11:    3      A 2020-03-15 03:23:00          2020-03-18 21:27:00
12:    3      X 2020-03-18 21:27:00

感谢任何帮助

谢谢

标签: rdata.table

解决方案


这是一种滚动连接的方法。

首先,我们对数据进行子集化Action == "A"Action == "X"然后将这两个子集相互连接。我们习惯于on = c("Case","Time")加入相同的案例,然后加入时间。在data.table中,您只能在最后一个连接条件上滚动。然后我们使用roll = Inf前滚。出于某种原因,您滚动的列在连接期间被合并,因此我们创建了一个名为InitialTime.

滚动连接向前滚动到正方向上的所有可能值,因此我们将和的所有组合的子集Case设置为最小值。TimeCaseInitialTime

library(data.table)
data[Action == "A",.(Case,Action,Time,InitialTime=Time)][
  data[Action == "X",], on = c("Case","Time"), roll = Inf][
    ,.SD[which.min(Time),.(XTime=Time)],by = .(Case,InitialTime)]
   Case         InitialTime               XTime
1:    1 2020-01-23 12:55:00 2020-04-16 17:50:00
2:    2 2020-01-25 23:04:00 2020-02-12 17:50:00
3:    3 2020-01-26 03:23:00 2020-02-18 21:27:00
4:    3 2020-03-15 03:23:00 2020-03-18 21:27:00

样本数据

data <- structure(list(Case = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 
3L, 3L), Action = structure(c(1L, 2L, 3L, 4L, 1L, 4L, 4L, 1L, 
3L, 4L, 1L, 4L), .Label = c("A", "B", "C", "X"), class = "factor"), 
    Time = structure(c(1579802100, 1580026980, 1580203380, 1587073800, 
    1580011440, 1581547800, 1581634200, 1580026980, 1582078980, 
    1582079220, 1584256980, 1584581220), class = c("POSIXct", 
    "POSIXt"), tzone = "")), row.names = c(NA, -12L), class = c("data.table", 
"data.frame"))

推荐阅读