user1256539
user1256539

Reputation:

Sequentially reorganize a vector in R

I have a numeric element z as below:

> sort(z)
  [1]  1  5  5  5  6  6  7  7  7  7  7  9  9

I would like to sequentially reorganize this element so to have

> z
  [1]  1  2  2  2  3  3  4  4  4  4  4  5  5  

I guess converting z to a factor and use it as an index should be the way.

Upvotes: 3

Views: 226

Answers (4)

droopy
droopy

Reputation: 2818

rep(seq_along(rle(x)$l), rle(x)$l)

Upvotes: 0

Ciarán Tobin
Ciarán Tobin

Reputation: 7526

You answered it yourself really:

as.integer(factor(sort(z)))

I know this has been accepted already but I decided to look inside factor() to see how it's done there. It more or less comes down to this:

x <- sort(z)
match(x, unique(x))

Which is an extra line I suppose but it should be faster if that matters.

Upvotes: 8

Paul Hiemstra
Paul Hiemstra

Reputation: 60944

Alternative using rle:

z = sort(sample(1:10, 100, replace = TRUE))
rle_result = rle(sort(z))
rep(rle_result$values, rle_result$lengths)

> rep(rle_result$values, rle_result$lengths)
  [1]  1  1  1  1  1  1  2  2  2  2  2  2  2  2  2  2  2  2  3  3  3  3  3  3  3
 [26]  3  3  3  4  4  4  4  4  4  4  4  5  5  5  5  5  5  5  5  5  5  5  6  6  6
 [51]  6  6  6  6  6  6  7  7  7  7  7  7  7  7  7  7  7  8  8  8  8  8  8  8  8
 [76]  8  8  8  8  8  8  9  9  9  9  9  9  9  9  9  9  9  9  9  9 10 10 10 10 10

Upvotes: 1

Paul Hiemstra
Paul Hiemstra

Reputation: 60944

This should do the trick

z = sort(sample(1:10, 100, replace = TRUE))
cumsum(diff(z)) + 1
 [1]  1  1  1  1  1  2  2  2  2  2  2  2  2  2  2  2  2  3  3  3  3  3  3  3  3
[26]  3  3  4  4  4  4  4  4  4  4  5  5  5  5  5  5  5  5  5  5  5  6  6  6  6
[51]  6  6  6  6  6  7  7  7  7  7  7  7  7  7  7  7  8  8  8  8  8  8  8  8  8
[76]  8  8  8  8  8  9  9  9  9  9  9  9  9  9  9  9  9  9  9 10 10 10 10 10

Note that diff omits the first element of the series. So to compensate:

c(1, cumsum(diff(z)) + 1)

Upvotes: 2

Related Questions