在R中基于行条件批量生成新行(无循环高效实现)
R 数据集扩展:将注册到注销年份拆分为逐年行(无循环实现)
原始数据集
df <- structure(list(id = c(1, 2, 2, 2), enrollment = c(2014, 2011, 2012, 2013), deregister = c(2016, 9999, 9999, 9999)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L))
目标数据集
target_df <- structure(list(id = c(1, 1, 1, 2, 2, 2), enrollment = c(2014, 2015, 2016, 2011, 2012, 2013), deregister = c(9999, 9999, 2016, 9999, 9999, 9999)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L))
需求逻辑
当deregister字段值不为9999时,生成从enrollment到deregister的逐年行,新增行的deregister设为9999,仅原deregister对应行保留原值;要求无循环实现,适配大数据量。
解决方案(向量化操作)
使用tidyverse工具集的向量化函数完成,避免循环,效率更高:
library(tidyverse) result_df <- df %>% # 生成年份序列:非9999的注销年份生成完整序列,否则仅保留注册年份 mutate(year_seq = map2(enrollment, deregister, ~if(.y != 9999) .x:.y else .x)) %>% # 将列表列拆分为多行 unnest(year_seq) %>% # 更新enrollment为拆分后的年份,设置deregister值 mutate( enrollment = year_seq, deregister = ifelse(year_seq == deregister, deregister, 9999) ) %>% # 移除临时辅助列 select(-year_seq) # 输出结果 print(result_df)
代码说明
map2:向量化处理每一行的enrollment和deregister,生成对应的年份序列,无需逐行循环,适配大数据场景。unnest:将存储年份序列的列表列拆分为独立行,实现行扩展。- 条件赋值:通过
ifelse判断,仅当拆分后的年份等于原始deregister值时保留原值,其余行设为9999,完全匹配需求。
内容的提问来源于stack exchange,提问作者SBA
相关产品推荐
相关产品推荐

