NickBraunagel
NickBraunagel

Reputation: 1599

R - Where element doesn't equal next element in vector

With a vector, say:

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

I need to know

Using the above example, the output would look something like:

i before after
3 1      2
7 2      1
9 1      3

I suppose I can convert the values into a data.frame and lag/shift the column but am wondering if there is a better approach. I am also trying to avoid looping over the vector, if possible.

I also don't need the results in data.frame / spreadsheet format; feel free to propose a different output format.

Upvotes: 1

Views: 573

Answers (2)

Maurits Evers
Maurits Evers

Reputation: 50668

Here is an option

idx <- which(a != c(a[-1], NA))
data.frame(
    i = idx,
    before = a[idx],
    after = a[idx + 1])
#  i before after
#1 3      1     2
#2 7      2     1
#3 9      1     3

You can roll everything into a function

f <- function(x) {
    idx <- which(x != c(x[-1], NA))
    data.frame(
        i = idx,
        before = x[idx],
        after = x[idx + 1])
}
f(a)

giving the same output as above.

Upvotes: 4

d.b
d.b

Reputation: 32548

with(rle(a), data.frame(i = head(cumsum(lengths), -1),
                        before = head(values, -1),
                        after = values[-1]))
#  i before after
#1 3      1     2
#2 7      2     1
#3 9      1     3

Upvotes: 3

Related Questions