如何按Site分组生成重复3次的Night序列(适配可变分组长度)
按Site分组为Night列生成重复3次的序列(适配可变行数)
问题说明
需要为数据框的Night列填充序列,规则如下:
- 每个数字重复3次
- 按
Site列分组,每组的序列从1重新开始 - 每个Site的记录行数不固定,固定长度的方法无法适配
示例预期效果:
| Site_date_time | Site | Night |
|---|---|---|
| 1_01012023_2200 | 1 | 1 |
| 1_01012023_2300 | 1 | 1 |
| 1_02012023_0000 | 1 | 1 |
| 1_02012023_2200 | 1 | 2 |
| 1_02012023_2300 | 1 | 2 |
| 1_03012023_0000 | 1 | 2 |
| 2_01012023_2100 | 2 | 1 |
| 2_01012023_2200 | 2 | 1 |
| 2_01012023_2300 | 2 | 1 |
| 2_02012023_2200 | 2 | 2 |
| 2_02012023_2300 | 2 | 2 |
| 2_03012023_0000 | 2 | 2 |
| 2_03012023_2200 | 2 | 3 |
| 2_03012023_2300 | 2 | 3 |
| 2_04012023_0000 | 2 | 3 |
基础数据框代码:
# 创建包含Site列的基础数据框 site <- c(rep(1, times=6), rep(2, times=9)) df <- data.frame(site)
之前的固定长度方法(如下)仅适用于每组行数固定的场景,无法适配可变行数:
library("dplyr") library("data.table") # 仅适用于每组行数固定的情况 site <- c(rep(1, times=6), rep(2, times=6)) df <- data.frame(site) group_by(df, site) %>% mutate(night = rep(c(1:3), each=3))
解决方案
方法1:使用dplyr
利用n()获取每组的行数,计算需要生成的序列长度,再用rep()生成每个数字重复3次的序列,最后用length.out=n()确保序列刚好覆盖当前组的所有行:
library(dplyr) df <- df %>% group_by(site) %>% mutate(night = rep(seq_len(ceiling(n() / 3)), each=3, length.out=n())) %>% ungroup()
方法2:使用data.table
用.N获取每组的行数,逻辑和dplyr一致,写法更简洁:
library(data.table) setDT(df) df[, night := rep(seq_len(ceiling(.N / 3)), each=3, length.out=.N), by=site]
效果验证
运行上述代码后,df的night列会和示例表格中的预期结果一致:
- Site=1有6行,生成
c(1,1,1,2,2,2) - Site=2有9行,生成
c(1,1,1,2,2,2,3,3,3)
内容的提问来源于stack exchange,提问作者Stacey Harwood
相关产品推荐
相关产品推荐

