我正在尝试使用dplyr的 group_by 和 cur_group_id() 函数创建一个 id 列。这很顺利,但是我希望 cur_group_id() 根据分组变量之一“重新启动”。
示例数据:
df <- data.frame(
X = c(1,1,1,1,1,2),
Y = c(1,1,1,2,2,3),
Z = c(1,1,2,3,3,4)
)
# which looks like this
df
X Y Z
1 1 1
1 1 1
1 1 2
1 2 3
1 2 3
2 3 4
Run Code Online (Sandbox Code Playgroud)
我当前的代码和输出:
library(dplyr)
library(magrittr)
df %<>%
group_by(X, Y, Z) %>%
mutate(ID = cur_group_id()) %>%
ungroup()
df
X Y Z ID
1 1 1 1
1 1 1 1
1 1 2 2
1 2 3 3
1 2 3 3
2 3 4 4
Run Code Online (Sandbox Code Playgroud)
但是,我希望 ID 计数器在达到新的 X 值后立即重新启动,如下所示:
df
X Y Z ID
1 1 1 1
1 1 1 1
1 1 2 2
1 2 3 3
1 2 3 3
2 3 4 1
Run Code Online (Sandbox Code Playgroud)
有没有办法很好地解决这个问题?先感谢您。
既然你要重新启动ID的每个X,你可以group_by X创造独特的ID为每个独特的价值Y和Z。
library(dplyr)
df %>%
group_by(X) %>%
mutate(ID = match(paste(Y, Z), unique(paste(Y, Z))))
# X Y Z ID
# <dbl> <dbl> <dbl> <int>
#1 1 1 1 1
#2 1 1 1 1
#3 1 1 2 2
#4 1 2 3 3
#5 1 2 3 3
#6 2 3 4 1
Run Code Online (Sandbox Code Playgroud)
在基础 R 中,您可以ave类似地使用:
df$ID <- with(df, ave(paste(Y, Z), X, FUN = function(x) match(x, unique(x))))
Run Code Online (Sandbox Code Playgroud)
如果你想cur_group_id()具体使用,你可以将每个值的数据拆分X并应用于cur_group_id每个数据帧。
df %>%
group_split(X) %>%
purrr::map_df(~.x %>% group_by(Y, Z) %>% mutate(ID = cur_group_id()))
Run Code Online (Sandbox Code Playgroud)