Reputation: 1599
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
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
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