按顺序出现对变量进行分组

Grouping variables by their sequential occurence

假设我有一个数据集:

RNGkind('Mersenne-Twister')
set.seed(24)
y = sample(c('a', 'b'),
           10, replace = T)
my.dataframe1 <- data.frame(y)
my.dataframe1
   y
1  a
2  a
3  b
4  b
5  b
6  b
7  a
8  b
9  b
10 a

我想创建另一个变量 (z),它根据 y 中的值出现的集群为它们分配一个分组值。在这种情况下,'cluster' 会有多个 ab 出现一次,具体取决于 a 还是 b 先出现。

例如,值 1 将分配给出现 ab 的行簇(行 1:6),值 2 将分配给第二组行(行 7:9)。

数据框看起来像这样:

   y z
1  a 1
2  a 1
3  b 1
4  b 1
5  b 1
6  b 1
7  a 2
8  b 2
9  b 2
10 a 1

它需要工作以便识别变化是 a 还是 b 首先出现在序列中,例如:

set.seed(42)
y = sample(c('a', 'b'),
           10, replace = T)
my.dataframe2 <- data.frame(y)
my.dataframe2
   y
1  b
2  b
3  a
4  b
5  b
6  b
7  b
8  a
9  b
10 b

这样我们仍然会得到相同的结果:

   y z
1  b 1
2  b 1
3  a 1
4  b 2
5  b 2
6  b 2
7  b 2
8  a 2
9  b 3
10 b 3

除了使用 c() 手动执行之外,我不知道如何使其自动化,尤其是对于超过 1000 行的数据集。

我们可以使用rle比较y列中的第一个值,然后使用cumsumrep生成序列。

my.dataframe1$z <- with(rle(my.dataframe1$y == my.dataframe1$y[1L]), 
                        rep(cumsum(values), lengths))
my.dataframe1

#   y z
#1  a 1
#2  a 1
#3  b 1
#4  b 1
#5  b 1
#6  b 1
#7  a 2
#8  b 2
#9  b 2
#10 a 3

数据

my.dataframe1 <- structure(list(y = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 1L, 2L, 
2L, 1L), .Label = c("a", "b"), class = "factor")), class = "data.frame", 
row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10"))

我们可以使用 inverse.rlerle

my.dataframe1$z  <- with(my.dataframe1, inverse.rle(within.list(rle(!is.na(match(y, y[1]))),
                     values <- cumsum(values))))
my.dataframe1$z 
#[1] 1 1 1 1 1 1 2 2 2 3

数据

my.dataframe1 <- structure(list(y = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 1L, 2L, 
2L, 1L), .Label = c("a", "b"), class = "factor")), class = "data.frame", 
row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10"))