从列中获取先前的值并在R中求差

时间:2017-12-12 22:35:42

标签: r data.table xts

我有一个关于从一列获取先前值并将其放入另一列的问题。我有一个data.table对象(可以很容易地转换为xts对象),如下所示:

dput输出如下:

structure(list(Time = structure(c(1122855314, 1122855315, 1122855316, 
1122855317, 1122855318, 1122855319, 1122855320, 1122955811, 1122955812, 
1122955813, 1122955814, 1123027212, 1123027213, 1123027214, 1123027215, 
1123027216, 1123027217), class = c("POSIXct", "POSIXt"), tzone = "Australia/Melbourne"), 
`Inventory_{t}` = c(0, 2, 2, 2, 5, 8, 3, 7, 6, 6, 1, 0, 1, 
1, 3, 3, 3), `Inventory_{t-1}` = c(0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0), `Delta Inventory_{t-1}` = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), .Names = c("Time", 
"Inventory_{t}", "Inventory_{t-1}", "Delta Inventory_{t-1}"), row.names = c(NA, 
-17L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x00000000028b0788>)

我想'填写'“Inventory_ {t-1}”,以便它提前一秒获取“Inventory_ {t}”中的值并将其放入该单元格中。同样,对于“Delta Inventory_ {t-1}”,我希望它等于Delta Inventory_{t-1} = Inventory_{t-1} - Inventory_{t-2} 我还应该注意,在每个新的一天开始时,“Inventory_ {t-1}”和“Delta Inventory_ {t-1}”的初始值必须为0.

有了这些信息,我想得到一个新的data.table / xts对象,如下所示:

structure(list(Time = structure(c(1122855314, 1122855315, 1122855316, 
1122855317, 1122855318, 1122855319, 1122855320, 1122955811, 1122955812, 
1122955813, 1122955814, 1123027212, 1123027213, 1123027214, 1123027215, 
1123027216, 1123027217), class = c("POSIXct", "POSIXt"), tzone = "Australia/Melbourne"), 
`Inventory_{t}` = c(0, 2, 2, 2, 5, 8, 3, 7, 6, 6, 1, 0, 1, 
1, 3, 3, 3), `Inventory_{t-1}` = c(0, 0, 2, 2, 2, 5, 8, 0, 
7, 6, 6, 0, 0, 1, 1, 3, 3), `Delta Inventory_{t-1}` = c(0, 
0, 2, 0, 0, 3, 3, 0, 7, -1, 0, 0, 0, 1, 0, 2, 0)), .Names = c("Time", 
"Inventory_{t}", "Inventory_{t-1}", "Delta Inventory_{t-1}"), row.names = c(NA, 
-17L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x00000000028b0788>)

问题是,如果我使用循环,这个问题对我来说非常简单,但由于我有这么多数据,我希望有更快的方法来做到这一点,所以如果有人可以帮我解决这个问题我我非常感谢,提前谢谢。

1 个答案:

答案 0 :(得分:1)

这可以使用shift()函数来解决。 OP要求每天重新开始计算。这是通过by =参数完成的:

z[, `:=`(`Inventory_{t-1}` = shift(`Inventory_{t}`, fill = 0),
         `Delta Inventory_{t-1}` = shift(`Inventory_{t}`, fill = 0) - 
           shift(`Inventory_{t}`, n = 2L, fill = 0)), by = .(Day = as.Date(Time))][]
                   Time Inventory_{t} Inventory_{t-1} Delta Inventory_{t-1}
 1: 2005-08-01 10:15:14             0               0                     0
 2: 2005-08-01 10:15:15             2               0                     0
 3: 2005-08-01 10:15:16             2               2                     2
 4: 2005-08-01 10:15:17             2               2                     0
 5: 2005-08-01 10:15:18             5               2                     0
 6: 2005-08-01 10:15:19             8               5                     3
 7: 2005-08-01 10:15:20             3               8                     3
 8: 2005-08-02 14:10:11             7               0                     0
 9: 2005-08-02 14:10:12             6               7                     7
10: 2005-08-02 14:10:13             6               6                    -1
11: 2005-08-02 14:10:14             1               6                     0
12: 2005-08-03 10:00:12             0               0                     0
13: 2005-08-03 10:00:13             1               0                     0
14: 2005-08-03 10:00:14             1               1                     1
15: 2005-08-03 10:00:15             3               1                     0
16: 2005-08-03 10:00:16             3               3                     2
17: 2005-08-03 10:00:17             3               3                     0