You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 11:09:51