1

my actual problem is, that I want to count the length of similar values in my vector, for example:

v <- c(1,1,1,1,2,1,1,3,3,3,1,1,2,2,2)

But additionally I want to omit all interruptions with the length 1. How can I achieve that my result here would be:

1,1,1,1,1,1,1,3,3,3,1,1,2,2,2

Note that the single "two" should now turn in a "one" and with

v_new <- c(1,1,1,1,1,1,1,3,3,3,1,1,2,2,2)

rle(v_new)
lengths: int [1:4] 7 3 2 3 
values : num [1:4] 1 3 1 2

Thanks, Mike

markus
  • 25,843
  • 5
  • 39
  • 58
Mike
  • 13
  • 2

2 Answers2

1
> v <- c(1,1,1,1,2,1,1,3,3,3,1,1,2,2,2)
> 
> local.peak <- which(diff(sign(diff(v)))==-2) + 1
> 
> v[which(diff(sign(diff(v)))==-2) + 1] <- v[local.peak - 1]
> v
 [1] 1 1 1 1 1 1 1 3 3 3 1 1 2 2 2

The local peak function is taken from Finding local maxima and minima

Kozolovska
  • 1,090
  • 6
  • 14
1

Below is a little function that replaces values that occur not more than one time in a row with either the value to the left or right of it.

Your input

v <- c(1,1,1,1,2,1,1,3,3,3,1,1,2,2,2)
fun(v)
# [1] 1 1 1 1 1 1 1 3 3 3 1 1 2 2 2

Modified input

v <- c(1,1,1,1,2,4,4,3,3,3,1,1,2,2,2)
#                ^ ^

Usage

fun(v, align = "right")
# [1] 1 1 1 1 4 4 4 3 3 3 1 1 2 2 2

Default is left aligned

fun(v)
# [1] 1 1 1 1 1 4 4 3 3 3 1 1 2 2 2

function

fun <- function(x, align = c("left", "right")) {
      align <- match.arg(align)
      rle_x <- rle(x)
      rle_x$values <- with(rle_x, replace(values, lengths == 1, NA))
      switch(align,
             left = approx(inverse.rle(rle_x), xout = seq_along(x), method = "constant", f = 0)$y,
             right = approx(inverse.rle(rle_x), xout = seq_along(x), method = "constant", f = 1)$y)
    }
markus
  • 25,843
  • 5
  • 39
  • 58