I want to find a list of previous max. So for a vector: 3, 2,2,3,4,3,9,5,2,3,4,6,120,1 The first max is 3, the second max is 4 (because, 4>3), then 9(because 9>4) and then 120 (120>9) So, as an output I would need the position: 1,5,7,13
Is there anyway to do this without a for loop?
```
vector<-c(3, 2,2,3,4,3,9,5,2,3,4,6,120,1)
results<-1
max<-3
for(i in 2:length(vector)){
if(vector[i]>max{
results<-c(results, i)
max<-vector[i]}
else {next}
}
```
CodePudding user response:
This can be done with run-length encoding:
vec <- c(3,2,2,3,4,3,9,5,2,3,4,6,120,1)
r <- rle(cummax(vec))
c(1, 1 cumsum(r$lengths)[-length(r$lengths)])
# [1] 1 5 7 13
And a variant from @user20650 that is shorter, more succinct (thanks!):
which(as.logical(c(1, diff(cummax(vec)))))
# [1] 1 5 7 13
CodePudding user response:
Maybe another solution with dplyr
and tibble
:
library(dplyr)
library(tibble)
cummax(vector) %>%
enframe() %>%
group_by(value) %>%
slice_head() %>%
pull(name)
[1] 1 5 7 13
CodePudding user response:
Another way is to use a recursive function
findAllMaximums <- function(data, index = 1, results = c()){
if(index == length(data)) return(results)
if(index==1) return(findAllMaximums(data, index 1, index))
if(data[index] > max(data[results])) results = append(results, index)
return(findAllMaximums(data, index 1, results))
}
vector<-c(3, 2,2,3,4,3,9,5,2,3,4,6,120,1)
print(findAllMaximums(vector))
CodePudding user response:
sapply(split(1:length(vector), cummax(vector)), `[`, 1)
## 3 4 9 120 <- the names of the result vector (=max values)
## 1 5 7 13 <- the values (=indexes)
Take only the firsts of the cummax()
grouping.