Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compress vector in (inverse of rep)

Tags:

r

I need to decompose a vector into a series of x and repeat, I am not really sure what the proper term for this is. It is the inverse of the rep function. So a vector

[1,2,2,2,2,1,1,1,1,1,2,2] -> [1x1, 4x2, 5x1, 2x2]

I wrote a little function to do this, but I am sure there must be a more native way:

invrep <- function(y){
  numy <- as.numeric(y);
  newpoints <- which(c(T,diff(numy) != 0));
  x <- y[newpoints];
  times <- diff(c(newpoints, length(numy)+1));
  return(list(x=x, times=times));
}

myvec <- factor(floor(runif(50,0,3)), levels=0:2, labels=c("blue", "yellow", "red"));
myrep <- invrep(myvec);
identical(myvec, rep(myrep$x, myrep$times));
like image 917
Jeroen Ooms Avatar asked May 14 '12 20:05

Jeroen Ooms


1 Answers

The rle function should do the trick:

> x <- c(1,2,2,2,2,1,1,1,1,1,2,2)
> y <- rle(x)
> y
Run Length Encoding
  lengths: int [1:4] 1 4 5 2
  values : num [1:4] 1 2 1 2
> inverse.rle(y)
 [1] 1 2 2 2 2 1 1 1 1 1 2 2
> rep(y$values, y$lengths)
 [1] 1 2 2 2 2 1 1 1 1 1 2 2

UPDATE As @TylerRinker commented, use as.character on factors:

myvec <- factor(sample.int(3,50,TRUE), levels=1:3, labels=c("blue", "yellow", "red"))
x <- rle(as.character(myvec))
y <- inverse.rle(x)
like image 118
Tommy Avatar answered Nov 15 '22 11:11

Tommy