6

I am struggling with calculating a "value reversal rate", e.g. the amount of value changes within a specific value range (= "Gap").

Data example:

a <- c(-30,0,20,23,24,25,26,27,28,29,30,5)
Gap <- 10

Goal:

Calculate the amount of value changes of 10, in this case the solution would be = 4

(1.change from -30 to 0, 2.change from 0 to 20, 3.change from 20,....,to 30, 4.change from 30 to 5)

Any help how to calculate this?

zx8754
  • 52,746
  • 12
  • 114
  • 209
funkfux
  • 283
  • 3
  • 14
  • Have you come up with an algorithm of how to approach this? If yes, please document that as well. – Roman Luštrik Nov 05 '18 at 09:28
  • No, unfortunately I did not figure out an algorithm so far... The final goal is a rate relative to the number of observations (in the example, the number of values in the vector a, not number of rows, sorry). But my question here mainly refers to the first step I am struggling with to calculate this rate, that is to count the number of value changes. – funkfux Nov 05 '18 at 09:48
  • yes, I also thought about sum(abs(diff))), but then failed due to the fact, that I do not only want to consider the difference between two adjacent observations... – funkfux Nov 05 '18 at 10:19

2 Answers2

1

Edited. Works on both examples now:

Gap <- 10

value_changes <- function(vec, gap) {
  res <- 0
  retain_min <- retain_max <- vec[1]
  cat("i:", 1, ", vec[i]:", vec[1], ", retain_min:", retain_min, ", retain_max:", retain_max, ", res:", res, "\n")
  for (i in 2:length(vec)) {
    if (abs(vec[i] - retain_min) >= gap || abs(vec[i] - retain_max) >= gap) {
      res <- res + 1
      retain_min <- retain_max <- vec[i]
    }
    if (vec[i] < retain_min) retain_min <- vec[i]
    if (vec[i] > retain_max) retain_max <- vec[i]
    cat("i:", i, ", vec[i]:", vec[i], ", retain_min:", retain_min, ", retain_max:", retain_max, "res:", res, "\n")
  }
  res
}
value_changes(c(5, 25, 17, 7, -2, 12), Gap)
value_changes(c(-30,0,20,23,24,25,26,27,28,29,30,5), Gap)

#i: 1 , vec[i]: 5 , retain_min: 5 , retain_max: 5 , res: 0 
#i: 2 , vec[i]: 25 , retain_min: 25 , retain_max: 25 res: 1 
#i: 3 , vec[i]: 17 , retain_min: 17 , retain_max: 25 res: 1 
#i: 4 , vec[i]: 7 , retain_min: 7 , retain_max: 7 res: 2 
#i: 5 , vec[i]: -2 , retain_min: -2 , retain_max: 7 res: 2 
#i: 6 , vec[i]: 12 , retain_min: 12 , retain_max: 12 res: 3 
#[1] 3
#
#i: 1 , vec[i]: -30 , retain_min: -30 , retain_max: -30 , res: 0 
#i: 2 , vec[i]: 0 , retain_min: 0 , retain_max: 0 res: 1 
#i: 3 , vec[i]: 20 , retain_min: 20 , retain_max: 20 res: 2 
#i: 4 , vec[i]: 23 , retain_min: 20 , retain_max: 23 res: 2 
#i: 5 , vec[i]: 24 , retain_min: 20 , retain_max: 24 res: 2 
#i: 6 , vec[i]: 25 , retain_min: 20 , retain_max: 25 res: 2 
#i: 7 , vec[i]: 26 , retain_min: 20 , retain_max: 26 res: 2 
#i: 8 , vec[i]: 27 , retain_min: 20 , retain_max: 27 res: 2 
#i: 9 , vec[i]: 28 , retain_min: 20 , retain_max: 28 res: 2 
#i: 10 , vec[i]: 29 , retain_min: 20 , retain_max: 29 res: 2 
#i: 11 , vec[i]: 30 , retain_min: 30 , retain_max: 30 res: 3 
#i: 12 , vec[i]: 5 , retain_min: 5 , retain_max: 5 res: 4 
#[1] 4
r.user.05apr
  • 5,356
  • 3
  • 22
  • 39
  • see my edit, when `a <- c(5, 25, 17, 7, -2, 12)` `value_changes(a, Gap)` returns `2` when it should return `3` imo. Do you have an idea on how to deal with this? – Niek Nov 05 '18 at 12:37
0

Maybe:

length(unique(cumsum(a %% Gap == 0)))
# [1] 4

This assumes you have "10s" in the data, e.g.: this will not work if we have:

a <- c(-31,1,21,23,24,25,26,27,28,29,32,5)
length(unique(cumsum(a %% Gap == 0)))
# [1] 1
zx8754
  • 52,746
  • 12
  • 114
  • 209