在 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
我想计算从第一行到当前行的最大值
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