I have such data
id Pos
1 1
2 10
3 4
4 2
5 3
6 16
What I want to do is take the difference between the rows of Pos
conditional on the id
. If id
is an odd number, then the difference is 1-10=-9
. If id
is an even number, the difference is 10-1=9
.
So I should get
difference
-9
9
2
-2
-13
13
I tried this
q <- ifelse( (id %% 1) == 0,(tail(Pos, -1) - head(Pos, -1)), (head(Pos, -1) - tail(Pos, -1)) )
but it worked for the odds number only.
Any idea how to do this in R?
Cheers
Günal
An option is to create a group for each two elements with gl
, take the diff
erence of 'Pos', rep
licate twice (or n()
), and change the sign based on the odd/even row_number()
library(dplyr)
df1 %>%
group_by(grp = as.integer(gl(n(), 2, n()))) %>%
mutate(Diff = rep(diff(Pos), n())) %>%
ungroup %>%
select(-grp) %>%
mutate(Diff = Diff * c(1, -1)[(id %%2) + 1])
# A tibble: 6 x 3
# id Pos Diff
# <int> <int> <dbl>
#1 1 1 -9
#2 2 10 9
#3 3 4 2
#4 4 2 -2
#5 5 3 -13
#6 6 16 13
If we need a solution with head/tail
from base R
i1 <- with(df1, rep((tail(Pos, -1) - head(Pos, -1))[c(TRUE, FALSE)], each = 2))
c(1, -1)[(df1$id %%2) + 1] * i1
#[1] -9 9 2 -2 -13 13
df1 <- structure(list(id = 1:6, Pos = c(1L, 10L, 4L, 2L, 3L, 16L)),
class = "data.frame", row.names = c(NA,
-6L))