-4

I made a function to increase a counter whenever the value in a vector changes:

track_change = function(x) {
  counter = numeric(length(x))
  for (i in seq_along(x)) {
    if (i > 1 && x[i] != x[i-1])
      counter[i] = counter[i-1] + 1
    else if (i > 1)
      counter[i] = counter[i-1]
  }
  counter
}

Example (see how track changes upon every change of carb):

mtcars$track = track_change(mtcars$carb)

head(mtcars[, 10:12])
                  gear carb track
Mazda RX4            4    4     0
Mazda RX4 Wag        4    4     0
Datsun 710           4    1     1
Hornet 4 Drive       3    1     1
Hornet Sportabout    3    2     2
Valiant              3    1     3

Is there a better way to do this in R? (It should also be able to track changes in non-numerical vectors, incl. lists.)

jakub
  • 4,774
  • 4
  • 29
  • 46

1 Answers1

2

We can do this with rleid from data.table

library(data.table)
rleid(mtcars$carb)-1

Or with rle from base R

inverse.rle(within.list(rle(mtcars$carb), values <- seq_along(values))) - 1
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Thanks. The `for loop` solution is actually about 5-10% faster than `rle` approach on my data (just FYI). – jakub Jan 08 '17 at 17:31
  • @jakub I would say that you should check the benchmarks on a bigger dataset i.e. around a million or more datapoints – akrun Jan 08 '17 at 17:35