基于R tidyverse按固定分块大小生成重复行的技术需求
解决方案:基于固定大小分块并生成重叠区间的重复行
核心思路
对于每个id对应的[start, end)区间,找出所有以req_sz为步长的连续块(块起始为req_sz的整数倍),只要原区间与块存在重叠(哪怕是部分重叠),就为该块生成一行记录。
实现代码
library(tidyverse) # 定义参数:min_sz是最小单位,req_sz必须是min_sz的倍数 min_sz = 2 req_sz = 20 # 原始数据 df = tibble( id = c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"), start = c(0, 0, 0, 4, 4, 8, 10, 10, 16, 32), end = c(4, 6, 16, 10, 22, 18, 36, 56, 42, 84), ) # 处理流程 df_processed <- df %>% # 计算原区间时长 mutate(dur = end - start) %>% # 计算当前区间覆盖的第一个块起始和最后一个块起始 mutate( first_chunk = floor(start / req_sz) * req_sz, # 减1是为了处理end刚好是req_sz倍数的情况,确保部分重叠的块被包含 last_chunk = floor((end - 1) / req_sz) * req_sz ) %>% # 生成每个区间对应的所有块起始序列 mutate(chunk_start = map2(first_chunk, last_chunk, ~seq(.x, .y, by = req_sz))) %>% # 展开序列,生成多行记录 unnest(chunk_start) %>% # 计算每个块的结束值 mutate(chunk_end = chunk_start + req_sz) %>% # 移除中间计算字段(可选) select(-first_chunk, -last_chunk) # 查看结果 print(df_processed, n = 10)
代码关键逻辑说明
first_chunk计算:通过floor(start / req_sz) * req_sz找到不大于start的最大req_sz倍数,作为当前区间覆盖的第一个块起始。last_chunk计算:用(end - 1)避免当end恰好是req_sz倍数时,误将下一个块纳入(比如end=20时,不会生成20-40的块);同时确保部分重叠的块被包含(比如end=22时,会生成20-40的块)。map2+unnest:为每个区间生成对应的所有块起始序列,再展开为多行,实现每个重叠块对应一行记录。
验证结果
以id=e(start=4,end=22)为例,处理后会生成两行:
- 块
0-20:与原区间4-22完全重叠 - 块
20-40:与原区间4-22部分重叠(20-22)
完全符合预期输出。
内容的提问来源于stack exchange,提问作者Ankit
相关产品推荐
相关产品推荐

