Jan*_* Lu 6 iteration row r data.table
我在R中关注了DT(data.table)。
dt <- fread("
id| rowids | charge | payment | balance
a | 1 | 7.1 | 0 |
a | 2 | 1.2 | 3 |
a | 3 | 1.7 | 1 |
b | 1 | 8.1 | 0 |
b | 2 | 2.5 | 4 |
b | 3 | 2.3 | 2 |
b | 4 | 3.2 | 1 |
",
sep = "|",
colClasses = c("character", "numeric", "numeric", "numeric",
"numeric"))
Run Code Online (Sandbox Code Playgroud)
应该在每个id组中将“余额”计算为“余额<-previous.row.balance +费用-付款”,其中“ previous.row.balance”是“ balance”的上一行条目。
我最初低估了计算平衡的难度。我在想dt[,previous.row.balance := (shift(balance,1),by=id]。但是R确实进行了矢量化计算。我没有“ balance”中的值可用于执行shift(),因为“ balance”将通过逐行迭代进行计算。
我搜索了StackOverflow,发现了一个类似的问题,它的第一个答案极大地帮助我思考了整个过程。我对问题的第一个答案改编了代码,并使以下代码出色地工作以按组生成运行平衡。
dt[rowids == 1, balance := charge, by=.(id)]
dt[rowids != 1, balance :=
dt[,
{
balance1 <- balance[1L]
.SD[rowids != 1,
{balance1 <- balance1 + charge - payment
.(balance1)
},
by=.(rowids)]
},
by=.(id)][, -1L:-2L]
]
Run Code Online (Sandbox Code Playgroud)
这是我的问题。
by=.(id)][, -1L:-2L],链式括号解决了迭代问题。由于该代码未使用shift() by = group,因此我猜想[, -1L:-2L]这里有技巧可以执行迭代。但是如何?什么是[, -1L:-2L]真正在这里做?抱歉,我必须在这里提出这个问题,而不是在该问题下发表评论或提出问题。原因是我是StackOverflow的新手,仅获得1点声誉。我不允许对这个问题的原始答案发表评论。我也想投票赞成这个答案。在我这样做之前,我必须获得更多积分。
任何见解或想法都将受到赞赏!
关于你的问题#2:
您可以使用该cumsum函数(输出与问题中的代码匹配)。charge - payment这将采用第一行的值,然后对于第二行,第二行将charge - payment添加到该值,依此类推。
dt[, balance2 := cumsum(charge - payment), id]
dt
# id rowids charge payment balance balance2
# 1: a 1 7.1 0 7.1 7.1
# 2: a 2 1.2 3 5.3 5.3
# 3: a 3 1.7 1 6.0 6.0
# 4: b 1 8.1 0 8.1 8.1
# 5: b 2 2.5 4 6.6 6.6
# 6: b 3 2.3 2 6.9 6.9
# 7: b 4 3.2 1 9.1 9.1
Run Code Online (Sandbox Code Playgroud)