【问题标题】:Distribute a monetary amount over rows until it depletes在行上分配货币数量,直到它耗尽
【发布时间】:2018-11-09 11:13:05
【问题描述】:

对于我拥有的特定数据帧,需要在我的数据帧上分配一定数量(POT)。当该数量耗尽时,它应该返回剩余的数据帧而不分配值。输入 DF:

Accepted    Jackpot Commision   Rank
NO          2760.33 279.85      1
NO          2760.33 279.85      1
NO          2760.33 279.85      1
NO          2760.33 279.85      1
NO          2760.33 206.38      2
NO          2760.33 206.38      2
NO          2760.33 206.38      2

如您所见,DF 有 4 列,但实际上要大得多,但这些列很重要。我想将 Accepted 更改为 Yes,同时根据 Rank 列用佣金耗尽 Jackpot。

因此,对于所有排名为 1 的行,头奖 - 佣金 (2760.33 - 279.85 = 2480.48) 变为“接受”。头奖现在为:2480.48。所以这就是我们可以用于 Rank 2 等等。直到我们达到 0 和简单的所有 Accepted 留在 NO。

Accepted    Jackpot Commision   Rank
YES         2760.33 279.85      1
YES         2760.33 279.85      1
YES         2760.33 279.85      1
YES         2760.33 279.85      1
NO          2480.48 206.38      2
NO          2480.48 206.38      2
NO          2480.48 206.38      2

我尝试了很多东西,比如By, (s)apply, for, aggregate 等等,但我没有设法得到正确的答案。任何帮助表示赞赏。

完整的测试数据框:

dput(tst_df)
structure(list(Accepted = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("NO", "YES"), class = "factor"), 
    Jackpot = c(2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 2760.33, 
    2760.33, 2760.33, 2760.33, 2760.33, 2760.33), Commision = c(12.71, 
    12.71, 12.71, 27.52, 27.52, 27.52, 27.52, 27.52, 16.94, 16.94, 
    16.94, 31.51, 31.51, 31.51, 31.51, 31.51, 3.72, 3.72, 16.68, 
    16.68, 16.68, 14.46, 14.46, 132.13, 132.13, 132.13, 132.13, 
    132.13, 132.13, 132.13, 132.13, 132.13, 132.13, 132.13, 132.13, 
    132.13, 132.13, 132.13, 132.13, 132.13, 132.13, 132.13, 132.13, 
    132.13, 132.13, 132.13, 132.13, 12.19, 12.19, 6.82, 6.82, 
    55.31, 55.31, 55.31, 55.31, 55.31, 55.31, 55.31, 13.01, 13.01, 
    155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 
    155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 
    155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 155.8, 
    155.8, 155.8, 155.8, 279.85, 279.85, 279.85, 279.85, 279.85, 
    279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 
    279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 
    279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 
    279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 279.85, 
    279.85, 279.85, 279.85, 279.85, 279.85, 1.86, 6.2, 6.2, 36.96, 
    36.96, 36.96, 36.96, 36.96, 36.96, 36.96, 36.96, 36.96, 9.3, 
    6.45, 8.26, 10.16, 10.16, 10.16, 10.16, 6.61, 5.78, 6.2, 
    18.59, 18.59, 18.59, 84.24, 84.24, 84.24, 84.24, 84.24, 84.24, 
    84.24, 84.24, 84.24, 84.24, 84.24, 31.19, 31.19, 31.19, 31.19, 
    31.19, 31.19, 167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 
    167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 
    167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 
    167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 167.78, 1.24, 
    3.81, 3.81, 4.13, 17.67, 17.67, 17.67, 17.67, 106.72, 106.72, 
    106.72, 106.72, 106.72, 106.72, 106.72, 106.72, 106.72, 106.72, 
    106.72, 106.72, 106.72, 106.72, 106.72, 106.72, 106.72, 9.3, 
    55.43, 55.43, 55.43, 55.43, 55.43, 55.43, 55.43, 2.23, 24.79, 
    24.79, 24.79, 24.79, 260.22, 260.22, 260.22, 260.22, 260.22, 
    260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 
    260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 
    260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 260.22, 
    260.22, 260.22, 3.51, 3.51, 3.51, 7.44, 4.29, 4.29, 6.61, 
    27.58, 27.58, 27.58, 27.58, 27.58, 27.58, 27.58, 115.08, 
    115.08, 115.08, 115.08, 115.08, 115.08, 115.08, 115.08, 115.08, 
    115.08, 115.08, 115.08, 115.08, 115.08, 115.08, 115.08, 206.38, 
    206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 
    206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 
    206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 
    206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 206.38, 
    206.38, 206.38, 206.38, 69.1, 69.1, 69.1, 69.1, 69.1, 69.1, 
    69.1, 69.1, 69.1, 69.1, 69.1, 69.1, 69.1, 4.63, 0, 6.69, 
    6.69, 6.69, 6.69, 66.85, 66.85, 66.85, 66.85, 66.85, 66.85, 
    66.85, 66.85, 66.85, 11.98), Rank = c(15L, 15L, 15L, 18L, 
    18L, 18L, 18L, 18L, 37L, 37L, 37L, 25L, 25L, 25L, 25L, 25L, 
    33L, 33L, 20L, 20L, 20L, 23L, 23L, 4L, 4L, 4L, 4L, 4L, 4L, 
    4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
    4L, 4L, 4L, 38L, 38L, 58L, 58L, 10L, 10L, 10L, 10L, 10L, 
    10L, 10L, 70L, 70L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 22L, 47L, 47L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 
    16L, 16L, 85L, 53L, 60L, 35L, 35L, 35L, 35L, 34L, 48L, 54L, 
    41L, 41L, 41L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 
    11L, 11L, 17L, 17L, 17L, 17L, 17L, 17L, 8L, 8L, 8L, 8L, 8L, 
    8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
    8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 42L, 31L, 31L, 32L, 21L, 
    21L, 21L, 21L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
    7L, 7L, 7L, 7L, 7L, 7L, 13L, 12L, 12L, 12L, 12L, 12L, 12L, 
    12L, 30L, 43L, 43L, 43L, 43L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
    5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
    5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 66L, 66L, 66L, 79L, 45L, 
    45L, 46L, 28L, 28L, 28L, 28L, 28L, 28L, 28L, 6L, 6L, 6L, 
    6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 
    9L, 9L, 104L, 26L, 29L, 29L, 29L, 29L, 14L, 14L, 14L, 14L, 
    14L, 14L, 14L, 14L, 14L, 57L)), .Names = c("Accepted", "Jackpot", 
"Commision", "Rank"), row.names = c(NA, -367L), class = "data.frame")

【问题讨论】:

  • 我可以删除重复的吗?
  • 不,这就是问题所在。每一行都是一个事务,所以我不能删除它。那是不利的一面。在这个例子中,我没有显示交易 ID。
  • 我正在考虑一个while循环,但必须有更好的方法来做到这一点。
  • 根据您的数据,似乎所有 Accepted 都将为 YES,即此数据集中的数量并未耗尽。这是正确的吗?不需要循环; cumsum 是解决方案的一部分。
  • @WeihuangWong 正是如此。但是,如果您以示例数据为例,可能是我们的头奖用完了(在这种情况下,这不是因为所有佣金的总和为 2178。如果不是这种情况,那么当头奖为 0 时,所有其他行都将被接受行应该保持没有。

标签: r for-loop dataframe aggregate apply


【解决方案1】:

在此数据集中,“累积奖金”似乎并未耗尽,因此解决方案很简单。也就是说,

library(dplyr)
tst_df %>%
  distinct() %>%
  arrange(Rank) %>%
  mutate(cumsum = cumsum(Commision), remaining = Jackpot - cumsum) 
#    Accepted Jackpot Commision Rank  cumsum remaining
# 1        NO 2760.33    279.85    1  279.85   2480.48
# 2        NO 2760.33    206.38    2  486.23   2274.10
# 3        NO 2760.33    155.80    3  642.03   2118.30
# 4        NO 2760.33    132.13    4  774.16   1986.17
# <snip>
# 48       NO 2760.33     13.01   70 2172.54    587.79
# 49       NO 2760.33      7.44   79 2179.98    580.35
# 50       NO 2760.33      9.30   85 2189.28    571.05
# 51       NO 2760.33      4.63  104 2193.91    566.42

假设我们将“累积奖金”设置为较小的数字。解决方法是找出量耗尽的Rank,然后将汇总表加入原始数据集:

new_df <- mutate(tst_df, Jackpot = 1000)
accepted <- new_df %>%
  distinct() %>%
  arrange(Rank) %>%
  mutate(cumsum = cumsum(Commision),
         remaining = Jackpot - cumsum,
         Accepted = if_else(remaining > 0, "YES", "NO")) 
head(accepted)
#   Accepted Jackpot Commision Rank  cumsum remaining
# 1      YES    1000    279.85    1  279.85    720.15
# 2      YES    1000    206.38    2  486.23    513.77
# 3      YES    1000    155.80    3  642.03    357.97
# 4      YES    1000    132.13    4  774.16    225.84
# 5       NO    1000    260.22    5 1034.38    -34.38
# 6       NO    1000    115.08    6 1149.46   -149.46

所以这里所有 4 或以下的 Ranks 的 Accepted 等于“YES”。终于

out <- left_join(select(accepted, Accepted, Rank), select(tst_df, -Accepted))

【讨论】:

  • 看起来真不错。我现在无法测试(不在我的笔记本电脑后面)。当它起作用时,我明天接受它!谢谢。
猜你喜欢
  • 1970-01-01
  • 2019-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 2021-03-22
相关资源
最近更新 更多