假设我有数据框
df <- data.frame(a = c(rep("a", 5), rep("b", 5), rep("a", 5)),
b = c(rep(1, 2), rep(2, 5), rep(1, 8)))
> df
a b
1 a 1
2 a 1
3 a 2
4 a 2
5 a 2
6 b 2
7 b 2
8 b 1
9 b 1
10 b 1
11 a 1
12 a 1
13 a 1
14 a 1
15 a 1
我想按a
和b
对数据进行分组,并在第三列中命名组(数字),但我为我的新组是具有上述组的其他值的组。所以我有小组a1
,a2
b2
,b1
和a1
。我想将第二个a1
视为新组。所以,结果应该是:
a b group
1 a 1 1
2 a 1 1
3 a 2 2
4 a 2 2
5 a 2 2
6 b 2 3
7 b 2 3
8 b 1 4
9 b 1 4
10 b 1 4
11 a 1 5
12 a 1 5
13 a 1 5
14 a 1 5
15 a 1 5
我能做到的唯一方法就是使用循环:
group <- numeric(nrow(df))
value <- 1
for (i in 1:nrow(df)) {
if (i == 1) {
group[i] <- value
} else {
if (all(df$a[i] == df$a[i - 1],
df$b[i] == df$b[i - 1])) {
group[i] <- value
} else {
value <- value + 1
group[i] <- value
}
}
}
df$group <- group
df
但这个解决方案不是很聪明。我可以使用dplyr
或不使用循环来执行类似的操作吗?
答案 0 :(得分:2)
尝试:
df <- data.frame(a = c(rep("a", 5), rep("b", 5), rep("a", 5)),
b = c(rep(1, 2), rep(2, 5), rep(1, 8)))
library(dplyr)
transmute(df,a,b,group=cumsum(ifelse(lag(a)!=a | lag(b)!=b | is.na(lag(a)),1,0)))
或者:
mutate(df,group=cumsum(ifelse(lag(a)!=a | lag(b)!=b | is.na(lag(a)),1,0)))
答案 1 :(得分:1)
您可以在unite
和tidyr
中使用rle
:
library(dplyr);library(tidyr)
df%>%
unite("a_b",a,b,remove=FALSE)%>%
mutate(group = {sq = rle(a_b); rep(seq_along(sq$lengths), sq$lengths)})
a_b a b group
1 a_1 a 1 1
2 a_1 a 1 1
3 a_2 a 2 2
4 a_2 a 2 2
5 a_2 a 2 2
6 b_2 b 2 3
7 b_2 b 2 3
8 b_1 b 1 4
9 b_1 b 1 4
10 b_1 b 1 4
11 a_1 a 1 5
12 a_1 a 1 5
13 a_1 a 1 5
14 a_1 a 1 5
15 a_1 a 1 5
答案 2 :(得分:1)
您可以使用dplyr::group_indices
获取一系列群组ID
gi <- group_indices(df, a, b)
gi
# [1] 1 1 2 2 2 4 4 3 3 3 1 1 1 1 1
然后只需将这些组ID添加到他们的cummax
ids <- cummax(gi) + gi
ids
# [1] 2 2 4 4 4 8 8 7 7 7 5 5 5 5 5
它们与您想要的输出不完全相同,但如果需要可以重新标记。他们将以任何方式作为集团指数。