R::data.table:使用先前的平衡和逐行迭代按组生成运行平衡

标签 r data.table iteration row

我在 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 点声誉。我不能对这个问题的原始答案发表评论。我也想为这个答案投票。在我能做到这一点之前,我必须获得更多的积分。
  • 有没有其他方法,使用 data.table 和 R 向量化计算来实现这个运行平衡目标,而不用为行迭代包装任何循环?

  • 任何见解或想法表示赞赏!

    最佳答案

    关于你的问题#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/

    相关文章:

    r - 如何在函数中编写 facet_wrap (ggplot2)

    python - 如何在python中向后循环?

    ruby - 用 ruby​​ 计算字符串中的元音

    r - 按因子将相对频率添加到数据框中

    r - plot.window(...) : need finite 'xlim' values 中的错误

    R 数据表 : keep column when grouping by expression

    javascript - 如何迭代对象中的内部对象/属性

    r - grepl 排除模式之前的一组单词

    r - 计算最高进先出交易

    r - 使用 ifelse 和 group by 改变 data.table 中的列