简体   繁体   中英

In R, create sequential 1 to N column based on values in other columns

Seems like a straightforward data manip problem, however we would like to avoid using a for loop that simply compares the values in each row. We have the following dataframe:

zed = data.frame(
  a = c(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1),
  b = c('a', 'a', 'b', 'b', 'b', 'c', 'c', 'd', 'd', 'd', 'd', 'd', 'e', 'e', 'a', 'a'),
  c = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 1, 1),
  stringsAsFactors = FALSE
)

output = zed = data.frame(
  a = c(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1),
  b = c('a', 'a', 'b', 'b', 'b', 'c', 'c', 'd', 'd', 'd', 'd', 'd', 'e', 'e', 'a', 'a'),
  c = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 1, 1),
  group = c(1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 9, 9),
  stringsAsFactors = FALSE
)

> output
   a b c group
1  1 a 1     1
2  1 a 1     1
3  1 b 1     2
4  1 b 1     2
5  1 b 1     2
6  1 c 1     3
7  1 c 2     4
8  1 d 2     5
9  2 d 2     6
10 2 d 2     6
11 2 d 2     6
12 2 d 3     7
13 2 e 3     8
14 2 e 3     8
15 1 a 1     9
16 1 a 1     9

The dataframe begins with the columns a , b , c , and we need to add the group column to the dataframe. The group column starts at 1, and increases sequentially if any of the values in a , b , c are different from their value in the previous row.

This is not quite as simple as doing a group_by() on a , b , c , as the same row can appear later, but not sequentially, in the dataframe (eg rows 1,2 == rows 15,16, however they are not the same group because they did not appear sequentially in the dataframe).

We can use

library(data.table)
setDT(zed)[, group := .GRP, .(rleid(a, b, c))]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM