Reputation: 747
I have 10 days of values, and for each day I want to know the max of the previous 4 days. If there aren't 4 days worth of values, then I want the max of the last 3 days, etc. Code example:
set.seed(131)
Index <- 1:10
Val <- c(sample(10, 10, replace = T))
df = data.frame(Index, Val)
dfoo = df %>%
mutate(Lag1 = lag(Val, 1, default = 0), #get last days value
Last4Max = rollmax(Lag1, 4, partial = T, fill = 0, align = "right")) #get max of last 4 days
This works for all but for day 2/3 since there aren't 4 values in Lag1 (day 1 should be 0/NA because there's no "previous" day).
Index Val Lag1 Last4Max
1 1 3 0 0
2 2 2 3 0
3 3 3 2 0
4 4 4 3 3
5 5 9 4 4
6 6 6 9 9
7 7 6 6 9
8 8 3 6 9
9 9 4 3 9
10 10 10 4 6
So Last4Max
should be 3 for index 2/3, and 0/NA for 1. Is there a way to change the width size to account for having width>rownumbers? My alternative is to create 4 variables for each lag (with default = 0) and then take the max of all 4. I know this would work but it seems clunky, and it'd limit me if I wanted to quickly do max of last 10 days on a bigger dataset.
Thanks
Upvotes: 2
Views: 137
Reputation: 269654
1) Note that:
?rollmax
it does not have a partial
argument; however, we can use rollapply
or rollapplyr
with a partial
argument and specify FUN = max
. rollapplyr
(and also rollmaxr
) with an r
on the end defaults to align = "right"
allowing one to avoid writing that argument outwidth
argument can specify a one-component list of offsets so to specify that the prior 4 elements are to be used we can specify width = list(-seq(4))
eliminating the need for a separate lag column.Putting all these together we get:
rollapplyr(Val, list(-seq(4)), max, partial = TRUE, fill = 0)
## [1] 0 3 3 3 4 9 9 9 9 6
2) Another way to do this is to use a width of 5 but not use the last element when taking the maximum. In this case we don't need fill = 0
since it is able to process each component of Val
leaving nothing to fill.
Max <- function(x) if (length(x) > 1) max(head(x, -1)) else 0
rollapplyr(Val, 5, Max, partial = TRUE)
2a) If we knew that all elements of Val
were non-negative then we could alternately use this shorter definition for Max
:
Max <- function(x) max(head(x, -1), 0)
Upvotes: 3