How to keep only first value in every sequence of duplicated values in R

Viewed 28

I am trying to create a subset where I keep the first value in each sequence of numbers in a column. I tried to use:

df %>% group_by(x) %>% slice_head(n = 1)

But it only works for the first instance of each sequence.

An example data where x column contains the repeated sequence can be seen below:

x = c(2,2,2,3,3,3,1,1,1,5,5,5,2,2,2,1,1,1,3,3,3)
y = c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)

df= data.frame(x,y)

> df
   x y
1  2 1
2  2 1
3  2 1
4  3 1
5  3 1
6  3 1
7  1 1
8  1 1
9  1 1
10 5 1
11 5 1
12 5 1
13 2 1
14 2 1
15 2 1
16 1 1
17 1 1
18 1 1
19 3 1
20 3 1
21 3 1

So the end result that I would like to achive is:

x = c(2,3,1,5,2,1,3)
y = c(1,1,1,1,1,1,1)

df= data.frame(x,y)

> df
  x y
1 2 1
2 3 1
3 1 1
4 5 1
5 2 1
6 1 1
7 3 1

Could you please help or point me to any useful existing topics as I haven't managed to find it?

Thanks

3 Answers

You can try rleid from package data.table

> library(data.table)

> setDT(df)[!duplicated(rleid(x))]
   x y
1: 2 1
2: 3 1
3: 1 1
4: 5 1
5: 2 1
6: 1 1
7: 3 1

Base R.

df[c(1, diff(df$x)) != 0, ]

Or also with helper functions from data.table.

library(data.table)
df[rowid(rleid(df$x)) == 1L, ]

#    x y
# 1  2 1
# 4  3 1
# 7  1 1
# 10 5 1
# 13 2 1
# 16 1 1
# 19 3 1

Using rle and match.

df[match(with(rle(df$x), values), df$x), ]
#     x y
# 1   2 1
# 4   3 1
# 7   1 1
# 10  5 1
# 1.1 2 1
# 7.1 1 1
# 4.1 3 1
Related