【问题标题】:Sequentially reduce values in a column in R顺序减少R中列中的值
【发布时间】:2016-12-14 18:18:33
【问题描述】:

我目前正在尝试将列中的值减少一定的总量,直到该数量达到零。例如在这段代码创建的数据框中:

df = data.frame(matrix(0,nrow=10,ncol=2))
colnames(df) <- c("AccountNumber", "BuyAmount")
overbuy <- 500000
df$AccountNumber <- seq(1:10)
df$BuyAmount <- c(35000, 220000, 240000, 0, 195000, 55000, 0, 280000, 65000, 105000)

>df
   AccountNumber BuyAmount
1              1     35000
2              2    220000
3              3    240000
4              4         0
5              5    195000
6              6     50000
7              7         0
8              8    280000
9              9     65000
10            10    105000

我试图将 BuyAmount 列中的非零值一次减少 5000,沿着该列运行,每次将 overbuy 的值减少 5000。第一次运行循环后,df 应该如下所示:

>df
   AccountNumber BuyAmount
1              1     30000
2              2    215000
3              3    235000
4              4         0
5              5    190000
6              6     45000
7              7         0
8              8    275000
9              9     60000
10            10    100000

overbuy 的值应该减少 40000 到 460000。我希望这个循环继续运行这些值,直到 overbuy 达到 0。理论上,df 会结束

>df
   AccountNumber BuyAmount
1              1         0
2              2    150000
3              3    170000
4              4         0
5              5    130000
6              6         0
7              7         0
8              8    210000
9              9         0
10            10     35000

一旦超买达到 0。我目前的尝试是:

while(overbuy > 0){
  for(1 in 1:10){
    ifelse(df$BuyAmount[i] != 0, df$BuyAmount[i] <- df$BuyAmount[i] - 5000, "")
    overbuy <- overbuy - 5000
  }
}

任何帮助将不胜感激!

【问题讨论】:

  • 您正在执行什么样的分析? dplyr 的某些部分肯定可以使您的代码更优雅,但它有助于理解全局。
  • 我目前有一个代码可以告诉我每个帐户的总购买金额,但由于舍入错误,它通常会超出几千美元(每个订单只能以 5000 美元为增量)。我想系统地减少这种超调,以确保我最终不会过度购买每个账户并将其记入借方。我在上面使用了一个极端的例子来表明,一旦一个值达到 0,它应该被排除在其余的迭代之外。
  • 将价格降低到能被 5000 整除的数字会不会更有用?这样您就可以在不超过价值的情况下获得最接近的出价。
  • 可能不会 - 我无法真正了解购买决策的细微差别。我曾试图在每个账户中将overbuy 的总数分成相等的手数,但如果我以 5000 的增量保持手数,它最终会出现大量购买不足,这是我必须做的。因此,如果超买量很小,则需要向下迭代地应用减少量,直到 overbuy 达到 0。
  • 您希望的停止条件是什么?您是否需要超买才能降至 0 或 460000?

标签: r dataframe while-loop sequencing


【解决方案1】:

我认为这可行,但它并不优雅,而且我可能还没有完全理解您的目标。如果没有,请告诉我,我会解决这个问题。

编辑:

while(overbuy > 0){
    for(i in 1:10){

        if(df$BuyAmount[i]!=0){
            overbuy <- overbuy - 5000
        }
        df$BuyAmount[i] <- pmax(0, df$BuyAmount[i] - 5000)

        print(overbuy)
        print(df)
        if(overbuy == 0) break
    }
}

【讨论】:

  • 我会补充一点,我得到的最终 df 与您的预期输出不完全相同。但我认为这符合你的问题的逻辑,所以也许错误在你的计算中?
  • 我认为这仍在迭代 0 个元素而不是跳过它们,但它肯定很接近。看起来它正在处理所有 10 个元素,并且在处理元素 == 0 时返回 0 或 -5000 的最大值,这就是我认为差异的来源。
  • 现在得到与您预期相同的输出。
【解决方案2】:

@mkt 看起来你只需要一行,if(df$BuyAmount[i] &lt;= 0) next

while(overbuy > 0){
    for(i in 1:10){
    if(df$BuyAmount[i] <= 0) next
    df$BuyAmount[i] <- pmax(0, df$BuyAmount[i] - 5000)
    overbuy <- overbuy - 5000 
    print(overbuy)
    print(df)
    if(overbuy == 0) break
    }
    if(overbuy == 0) break
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 2013-11-12
    • 1970-01-01
    • 2022-11-27
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多