如何使用dplyr基于含两类变量的列生成连续编号的分组列
如何使用dplyr基于含两类变量的列生成连续编号的分组列
没问题,这在dplyr里其实很容易实现,核心思路是识别出daytime列的分组切换点,然后对这些切换点累计计数,就能得到你要的nightcount列了。
先把你的原始数据重现一下(方便测试):
library(dplyr) # 原始数据 df <- structure(list(Date = structure(c(1630544400, 1630548000, 1630551600, 1630555200, 1630558800, 1630562400, 1630566000, 1630569600, 1630573200, 1630576800, 1630580400, 1630630800, 1630634400, 1630638000, 1630641600, 1630645200, 1630648800, 1630652400, 1630656000, 1630659600), tzone = "America/Chicago", class = c("POSIXct", "POSIXt")), daytime = c("Night", "Night", "Night", "Night", "Morning", "Morning", "Morning", "Morning", "Morning", "Morning", "Morning", "Night", "Night", "Night", "Night", "Morning", "Morning", "Morning", "Morning", "Morning")), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"))
接下来就是处理代码,一行就能搞定核心逻辑:
df <- df %>% mutate(nightcount = cumsum(daytime != lag(daytime, default = first(daytime)))) + 1
解释一下这行代码的作用:
lag(daytime, default = first(daytime)):获取当前行的上一行daytime值,第一行没有上一行,所以用default指定为第一行自己的daytime值。daytime != lag(...):比较当前行和上一行的daytime是否不同,不同的话返回TRUE(对应数值1),相同返回FALSE(对应数值0)。cumsum():对上面的结果累加,这样每次分组切换的时候,累加值就会+1,刚好对应连续分组的编号。- 最后
+1是因为初始累加值是0,我们需要从1开始计数。
运行完之后,你就能得到和示例完全一致的nightcount列了,看看结果:
print(df)
输出会和你想要的一样:
Date daytime nightcount
1 2021-09-01 20:00:00 Night 1
2 2021-09-01 21:00:00 Night 1
3 2021-09-01 22:00:00 Night 1
4 2021-09-01 23:00:00 Night 1
5 2021-09-02 00:00:00 Morning 1
6 2021-09-02 01:00:00 Morning 1
...(后面的行也会正确对应编号)
另外,如果你觉得分步写更清晰,也可以拆成两步,先生成切换标记,再累加:
df <- df %>% mutate( group_switch = daytime != lag(daytime, default = first(daytime)), nightcount = cumsum(group_switch) + 1 ) %>% select(-group_switch) # 不需要的话可以删掉中间列
这样逻辑更直观,适合新手理解~
备注:内容来源于stack exchange,提问作者Ryan Gary
相关产品推荐
相关产品推荐

