简体   繁体   中英

Finding a list of previous max values in order of a vector R

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}
}
```

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

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))

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
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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM