[英]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
将值从一列和一行复制或转发到不同的列和行。 我用merge
和rbindlist
完成了这个,但我想知道是否有一个更简约的解决方案。
这是一个玩具示例:假设我在不同日期跟踪不同支票账户的期初和期末余额。 我希望将前一天的( 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.