在R语言中基于多布尔条件处理事件数据格式化问题
问题:将事件数据按Epoch区间转换为二进制格式
现有包含事件及其对应Epoch编号的数据集,需重新格式化为按特定Epoch区间记录各事件类型是否发生的二进制格式:
当前数据集:
## Current Dataframe: df <- data.frame( Epoch = c(99,126,136,148,150,200,228,247,268,269,285,285,294,308,309,319,320,324,326,337,338,352,353,380,382,418,419,424,431,437,440,447,449,470,515,548,550,550,561,589,590,596,598,603,612,616,623,626,633,655,663,668,682,687,704,708,717,730,744,752,771,794,810,811,816,819,825,832,832,841,847,851,853,868,871,881,893,915,918,922,935,943), Event = c("hypopnea","auto_trig","double_trig","auto_trig","double_trig","double_trig","hypopnea","hypopnea","auto_trig","double_trig","auto_trig","double_trig","double_trig","auto_trig","double_trig","auto_trig","double_trig","auto_trig","double_trig","double_trig","hypopnea","hypopnea","double_trig","double_trig","hypopnea","double_trig","hypopnea","double_trig","high_leak","auto_trig","double_trig","auto_trig","double_trig","double_trig","double_trig","hypopnea","auto_trig","double_trig","hypopnea","double_trig","auto_trig","double_trig","auto_trig","double_trig","double_trig","auto_trig","auto_trig","hypopnea","double_trig","double_trig","double_trig","auto_trig","double_trig","auto_trig","hypopnea","double_trig","double_trig","double_trig","double_trig","ineffective_eff","ineffective_eff","double_trig","double_trig","high_leak","double_trig","hypopnea","auto_trig","hypopnea","double_trig","high_leak","double_trig","high_leak","auto_trig","double_trig","double_trig","double_trig","double_trig","auto_trig","double_trig","double_trig","double_trig","double_trig") )
目标数据框结构:
df2 <- data.frame( Section = seq(1, max(df$Epoch/10+1), by = 1), Epoch5 = seq(1, max(df$Epoch), by =10), Epoch51 = seq(11, max(df$Epoch)+10, by = 10) )
要求:针对每种事件类型新增一列,当df$Epoch落在df2的Epoch5(含)到Epoch51(不含)区间,且事件匹配时,对应列设为1;未发生则设为0。
解决方案:使用dplyr+tidyr实现区间匹配与格式转换
可以通过以下步骤高效完成转换,避免循环和数据缺失问题:
- 给原始数据标记所属区间:计算每个Epoch对应的Section,让原始数据和目标区间关联
- 标记区间内的事件存在性:按Section和Event分组,标记该区间是否出现过该事件
- 转换为宽格式:将事件类型转为列,填充未出现事件的区间为0
- 合并到目标数据框:确保所有区间都被覆盖,补全缺失值
具体代码如下:
library(dplyr) library(tidyr) # 1. 给df添加对应的Section,匹配df2的区间规则 df_with_section <- df %>% mutate( Section = ceiling(Epoch / 10) # 按每10个Epoch为一个区间,计算所属Section ) # 2. 按Section和Event分组,标记该区间是否有该事件(存在则为1) event_flags <- df_with_section %>% group_by(Section, Event) %>% summarise(flag = 1, .groups = "drop") # 3. 转换为宽格式,每个事件作为一列,未出现的事件填充0 event_wide <- event_flags %>% pivot_wider( names_from = Event, values_from = flag, values_fill = 0 # 没有对应事件的区间填充0 ) # 4. 和df2合并,确保所有Section都包含在内,补全缺失的事件列为0 final_df <- df2 %>% left_join(event_wide, by = "Section") %>% mutate(across(-c(Section, Epoch5, Epoch51), ~replace_na(., 0))) # 查看结果 head(final_df)
代码说明:
- 区间匹配:用
ceiling(Epoch/10)直接计算每个Epoch对应的Section,和df2的区间规则完全匹配(比如Epoch=99对应Section=10,对应df2中Epoch5=91、Epoch51=101的区间) - 分组标记:通过
group_by+summarise快速标记每个区间内出现的事件,避免重复计数(即使同一区间同一事件出现多次,也只标记为1) - 宽格式转换:
pivot_wider自动将事件类型转为列,values_fill=0保证未出现事件的位置填充0 - 合并补全:
left_join确保df2的所有区间都被保留,replace_na把合并后缺失的事件列值补为0
这样处理后,就能得到每个区间各事件是否发生的二进制格式数据,不会出现数据缺失问题。
内容的提问来源于stack exchange,提问作者AR459
相关产品推荐
相关产品推荐

