我在 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"))
“余额”应在每个 id 组内计算为“余额 <- previous.row.balance + 费用 - 付款”,其中“previous.row.balance”是“余额”的前一行条目。
我最初低估了计算运行平衡的难度。我在想
dt[,previous.row.balance := (shift(balance,1),by=id]
.但 R 进行矢量化计算。我没有可用于执行 shift() 的“balance”值,因为“balance”将通过逐行迭代计算。我在 StackOverflow 上搜索并找到了 similar question and its first answer极大地帮助了我思考整个过程。我在我的问题的第一个答案中修改了代码,并使以下代码出色地工作以按组生成运行平衡。
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]
]
这是我的问题。
by=.(id)][, -1L:-2L]
,链式括号完成了迭代。由于代码没有使用 shift() by = group
, 我猜 [, -1L:-2L]
在这里执行迭代的技巧。但是如何?什么[, -1L:-2L]
真的在这里吗? 抱歉,我不得不在这里问这个问题,而不是在that question下评论或询问.原因是我是 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
关于R::data.table:使用先前的平衡和逐行迭代按组生成运行平衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58172310/