【问题标题】:Keeping the max within a group constant within a group using base::cumsum使用 base::cumsum 在组内保持组内的最大值不变
【发布时间】:2021-11-01 21:47:21
【问题描述】:

使用下面的数据使cumsum_a 列看起来像should 列。

开始的数据:

> demo
    th seq group
1 20.1   1    10
2 24.1   2    10
3 26.1   3    10
4  1.1   1    20
5  2.1   2    20
6  4.1   3    20

下面的“应该”列是目标。

demo<-data.frame(th=c(c(20.1,24.1,26.1),(c(1.1,2.1,4.1))),
    seq=(c(1:3,1:3)),group=c(rep(10,3),rep(20,3)))

library(magrittr)
library(dplyr)

demo %>% 
    group_by(group) %>%
        mutate(
    cumsum_a= cumsum((group)^seq*
            (((th)/cummax(th)))))%>%  
        ungroup()%>%
        mutate(.,
  cumsum_m=c( #As an example only, this manually does exactly what cumsum_a is doing (which is wrong)
        10^1*20.1/20.1,   #good
        10^1*20.1/20.1 + 10^2*24.1/24.1,            #different denominators, bad       
        10^1*20.1/20.1 + 10^2*24.1/24.1 + 10^3*26.1/26.1, #different denominators, bad
        20^1*1.1/1.1, #good
        20^1*1.1/1.1 + 20^2*2.1/2.1, #different denominators, bad
        20^1*1.1/1.1 + 20^2*2.1/2.1 + 20^3*4.1/4.1 #different denominators, bad
    ),
  should=c( #this is exactly the kind of calculation I want
        10^1*20.1/20.1,  #good
        10^1*20.1/24.1 + 10^2*24.1/24.1,        #good
        10^1*20.1/26.1 + 10^2*24.1/26.1 + 10^3*26.1/26.1, #good
        20^1*1.1/1.1, #good
        20^1*1.1/2.1 + 20^2*2.1/2.1, #good
        20^1*1.1/4.1 + 20^2*2.1/4.1 + 20^3*4.1/4.1 #good
    )

)

最简单地说,每行的分母必须相同,因此在cumsum_m 的第二行或cumsum_a 的基础计算中,24.1 和 24.1 而不是 20.1 和 24.1。

这里是新列,其中shouldcumsum_acumsum_m 应该是什么。

     th   seq group cumsum_a cumsum_m should
  <dbl> <int> <dbl>    <dbl>    <dbl>  <dbl>
1  20.1     1    10       10       10    10 
2  24.1     2    10      110      110   108.
3  26.1     3    10     1110     1110  1100.
4   1.1     1    20       20       20    20 
5   2.1     2    20      420      420   410.
6   4.1     3    20     8420     8420  8210.

【问题讨论】:

  • 你的意思是an列的结果是错误的?
  • 是的,这是错误的。 Should 是对的(我把名字从an 改成了cumsum_a
  • 在你最后一次手动计算中有一个3.1 值应该是4.1,这样你的结果就会和我的匹配。
  • 3.1 更改为4.1,最终结果为should
  • 好的很好。我现在将解释我在解决方案中做了什么。

标签: r purrr rolling-computation cumsum accumulate


【解决方案1】:

您可以使用以下解决方案:

  • purrr::accumulate 接受两个参数函数,第一个由 .x..1 表示的是先前迭代的累加值,.y 表示我们向量 (2:n()) 的当前值。所以我们的第一个累加值将是group 值的第一个元素,因为我将它作为.init 参数提供
  • 由于您想更改先前迭代/计算的分母,我将结果.x 乘以先前值cmax 与当前值cmax 的比值

我认为其余的很清楚,但如果您对此有任何疑问,请告诉我。

library(dplyr)
library(purrr)

demo %>%
  group_by(group) %>%
  mutate(cmax = cummax(th), 
         should = accumulate(2:n(), .init = group[1], 
                             ~ (.x * cmax[.y - 1] / cmax[.y]) + (group[.y] ^ seq[.y]) * (th[.y] / cmax[.y])))

# A tibble: 6 x 5
# Groups:   group [2]
     th   seq group  cmax should
  <dbl> <int> <dbl> <dbl>  <dbl>
1  20.1     1    10  20.1    10 
2  24.1     2    10  24.1   108.
3  26.1     3    10  26.1  1100.
4   1.1     1    20   1.1    20 
5   2.1     2    20   2.1   410.
6   4.1     3    20   4.1  8210.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-27
    • 2020-09-03
    • 2017-06-08
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    相关资源
    最近更新 更多