在 R 中滚动最大值。从第一行到当前行

Roll max in R. From first row to current row

我想计算从第一行到当前行的最大值

df <- data.frame(id = c(1,1,1,1,2,2,2), value = c(2,5,3,2,4,5,4), result = c(NA,2,5,5,NA,4,5))

我曾尝试使用 dplyr 按 id 分组并使用 zoo 中的 rollmax 函数,但没有成功

library(dplyr)
df |> 
  group_by(id) |>
  mutate(result = lag(cummax(value)))

# # A tibble: 7 x 3
# # Groups:   id [2]
#      id value result
#   <dbl> <dbl>  <dbl>
# 1     1     2     NA
# 2     1     5      2
# 3     1     3      5
# 4     1     2      5
# 5     2     4     NA
# 6     2     5      4
# 7     2     4      5

这是一个基本的 R 解决方案。这只会让你累积最大值:

df$result = ave(df$value, df$i, FUN=cummax)

要获得具有所需滞后的累积最大值:

df$result = ave(df$value, df$i, FUN=function(x) c(NA,cummax(x[-(length(x))])))

1) rollmax 用于固定宽度,但这里我们有可变宽度,所以使用 rollapplyr,这似乎接近问题的方法,我们有:

library(dplyr)
library(zoo)

df %>%
 group_by(id) %>%
 mutate(out = lag(rollapplyr(value, 1:n(), max))) %>%
 ungroup

给予:

# A tibble: 7 x 4
# Groups:   id [2]
     id value result   out
  <dbl> <dbl>  <dbl> <dbl>
1     1     2     NA    NA
2     1     5      2     2
3     1     3      5     5
4     1     2      5     5
5     2     4     NA    NA
6     2     5      4     4
7     2     4      5     5

2) 也可以通过 rollapplyr 的 width(第二个)参数进行分组,就像这样消除 dplyr。在这种情况下,宽度为 1、2、3、4、1、2、3,并且 Max 类似于 max,只是它不使用其参数 x 的最后一个元素。 (宽度的替代表达式是 seq_along(id) - match(id, id) + 1)。

library(zoo)

Max <- function(x) if (length(x) == 1) NA else max(head(x, -1))
transform(df, out = rollapplyr(value, sequence(rle(id)$lengths), Max))

给予:

  id value result out
1  1     2     NA  NA
2  1     5      2   2
3  1     3      5   5
4  1     2      5   5
5  2     4     NA  NA
6  2     5      4   4
7  2     4      5   5

data.table 选项使用 shift + cummax

> setDT(df)[, result2 := shift(cummax(value)), id][]
   id value result result2
1:  1     2     NA      NA
2:  1     5      2       2
3:  1     3      5       5
4:  1     2      5       5
5:  2     4     NA      NA
6:  2     5      4       4
7:  2     4      5       5