繁体   English   中英

如何使用R data.table将值从一行和一列(“单元格”)复制(“结转”)到不同的行和列?

[英]How to copy (“carry forward”) values from one row and column (“cell”) to a different row and column with R data.table?

我有一个R data.table 我想根据一个key将值从一列和一行复制或转发到不同的列和行。 我用mergerbindlist完成了这个,但我想知道是否有一个更简约的解决方案。

这是一个玩具示例:假设我在不同日期跟踪不同支票账户的期初和期末余额。 我希望将前一天的( t-1 )期末余额结转到当天的( t )期初余额。

有这个输入:

> DT_in <- data.table(date = c("2017-12-29", "2017-12-29", "2017-12-29", "2018-01-02", 
+                         "2018-01-02", "2018-01-02", "2018-01-02", "2018-01-03", 
+                         "2018-01-03", "2018-01-03", "2018-01-03"), 
+                  account_id = c("A17", "A23", "B21", "A17", "A23", "B21", "C12", 
+                                 "A17", "A23", "B21", "C12"),
+                  opening_balance = NA,
+                  ending_balance = c(224, 254, 240, 290, 107, 272, 105, 256, 215, 
+                                     202, 238)
+                  )
> DT_in
          date account_id opening_balance ending_balance
 1: 2017-12-29        A17              NA            224
 2: 2017-12-29        A23              NA            254
 3: 2017-12-29        B21              NA            240
 4: 2018-01-02        A17              NA            290
 5: 2018-01-02        A23              NA            107
 6: 2018-01-02        B21              NA            272
 7: 2018-01-02        C12              NA            105
 8: 2018-01-03        A17              NA            256
 9: 2018-01-03        A23              NA            215
10: 2018-01-03        B21              NA            202
11: 2018-01-03        C12              NA            238

想要这个输出:

> DT_out <- data.table(date = c("2017-12-29", "2017-12-29", "2017-12-29", "2018-01-02", 
+                           "2018-01-02", "2018-01-02", "2018-01-02", "2018-01-03", 
+                           "2018-01-03", "2018-01-03", "2018-01-03"), 
+                  account_id = c("A17", "A23", "B21", "A17", "A23", "B21", "C12", 
+                                 "A17", "A23", "B21", "C12"),
+                  opening_balance = c(NA, NA, NA, 224, 254, 240, NA, 290, 107, 272, 105), 
+                  ending_balance = c(224, 254, 240, 290, 107, 272, 105, 256, 215, 
+                                     202, 238)
+                  )
> DT_out
          date account_id opening_balance ending_balance
 1: 2017-12-29        A17              NA            224
 2: 2017-12-29        A23              NA            254
 3: 2017-12-29        B21              NA            240
 4: 2018-01-02        A17             224            290
 5: 2018-01-02        A23             254            107
 6: 2018-01-02        B21             240            272
 7: 2018-01-02        C12              NA            105
 8: 2018-01-03        A17             290            256
 9: 2018-01-03        A23             107            215
10: 2018-01-03        B21             272            202
11: 2018-01-03        C12             105            238

请注意, account_id不一定是从一个日期到下一个日期的持久性(可以添加新的或旧的删除)。 虽然没关系,但请注意,日期是营业日期而不是日历日期。

如果修复示例数据,则使用相同的数据类型“opening_balance”和“ending_balance”列

...
opening_balance = NA_real_,
...

您可以使用此代码向每个组执行最后一次观察(在应用正确的顺序/排序后!):

setorder(DT_in, account_id, date)
DT_in[, opening_balance := shift(ending_balance, 1), by = .(account_id)]

这导致(排序输出):

> DT_in
          date account_id opening_balance ending_balance
 1: 2017-12-29        A17              NA            224
 2: 2018-01-02        A17             224            290
 3: 2018-01-03        A17             290            256
 4: 2017-12-29        A23              NA            254
 5: 2018-01-02        A23             254            107
 6: 2018-01-03        A23             107            215
 7: 2017-12-29        B21              NA            240
 8: 2018-01-02        B21             240            272
 9: 2018-01-03        B21             272            202
10: 2018-01-02        C12              NA            105
11: 2018-01-03        C12             105            238

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM