0

I am using below code to list out Peaks and Valleys.

x_last <- as.numeric(series[1])
x <- as.numeric(series[2])
d_last <- (x-x_last)
series[1:2] <- NULL
output <- list()

for (x_next in series){
  if (x_next == x){
    next}
  d_next <- (x_next - x)
  if (d_last * d_next < 0){
    output <- append(output, x)}
  x_last <- x
  x <- x_next
  d_last <- d_next
}

Here Output(list) contains "continuous Peaks and Valleys".

Output <- c(41.49916, 37.92029, 39.86477, 39.86432, 39.95672, 39.95465, 39.96144, 39.83994, 40.43357, 40.11285, 40.82250, 39.37034, 58.82975, 42.19894)

so on...

enter image description here the graph plotted using Output(list). My question is how to add threshold in this code? or how can i remove small Peaks and Valleys(values less than 1). I Need continuous Peaks and valleys.

Looking for answers. thank you in advance.

Rudesh_Bala
  • 85
  • 10

2 Answers2

0

If you just want to plot your data:

You could plot this with ggplot2 and add a geom_smooth() layer. It defaults to method "loess" which is kind of a "do-the-right-thing" smoother for small datasets.

dat <- data.frame(y=c(41.49916, 37.92029, 39.86477, 39.86432, 39.95672, 39.95465, 39.96144, 39.83994, 40.43357, 40.11285, 40.82250, 39.37034, 58.82975, 42.19894))
dat$x <- 1:length(dat$y)
library(ggplot2)

ggplot(dat, aes(x, y)) +
        geom_line() +
        geom_smooth(method="loess", se=FALSE) 

enter image description here?

Or do you rather want to smoothen the data yourself? (Your data series is quite short for that.) Do you need an equation for the fit? It's easy to spend quite some time on that.

I don't fully understand this "peak/valley" stuff. In any case, take a look at the diff() function. Maybe this helps:

dat <- data.frame(y=c(41.49916, 37.92029, 39.86477, 39.86432, 39.95672, 39.95465, 39.96144, 39.83994, 40.43357, 40.11285, 40.82250, 39.37034, 58.82975, 42.19894))
dat[which(diff(dat$y) < 0.01)+1,"y"] <- NA
dat$y

 [1] 41.50    NA 39.86    NA 39.96    NA    NA    NA 40.43    NA 40.82    NA
[13] 58.83    NA

Here I've used a threshold of 0.01. I'm not sure if it's the right thing. But you can adapt this code for your needs.

knb
  • 9,138
  • 4
  • 58
  • 85
  • Thanks for your reply, I doesn't want to plot this data. I want to remove small cycles in this data and also want to Keep Peak and valley(Peak,valley,Peak,valley... like that). From my knowledge it is called threshold (Magnitude), difference between Peak and valley is less than threshold than it has to be removed. – Rudesh_Bala Jul 05 '17 at 07:33
  • @ruth added 1 paragraph my answer – knb Jul 05 '17 at 08:31
0

At last I created a function to remove small cycles also to maintain Peak and valley. For me it is working perfectly.

hysteresis <- function(series, min_range){ 
  #hysteresis function will remove cycles within the magnitude of min_range
  #Series: list of values with continuous Peak & valley. 
  series <- unlist(series)
  f <- series[1]
  org <- f
  series <- series[2:length(series)]
  for(i in series){
    val <- abs(i-f)
    if(val > min_range){
      org <- c(org,i)
      f <- i
    }
    #else statement is used to maintain peak and valley
    else{
      org <- org[1:(length(org)-1)]
      f <- org[length(org)]
    }
  }
  return(org)
} 
Rudesh_Bala
  • 85
  • 10