如何用Base R简化不同预约次数患者的缺席率计算?
更简便的Base R实现患者预约缺席率计算
问题背景
我们有如下患者预约数据集,记录了患者的预约出席/缺席情况:
set.seed(123) num_patients <- 50 patient_ids <- rep(1:num_patients, each = sample(2:10, num_patients, replace = TRUE)) n_visits <- length(patient_ids) start_date <- as.Date("2022-01-01") end_date <- as.Date("2023-12-31") visit_dates <- sample(seq(start_date, end_date, by = "day"), n_visits, replace = TRUE) results <- sample(c("miss", "attend"), n_visits, replace = TRUE, prob = c(0.25, 0.75)) patient_visits <- data.frame( patient_id = patient_ids, visit_date = sort(visit_dates[order(patient_ids)]), result = results )
需要计算以下场景的缺席率:
- 仅1次预约的患者:首次预约的缺席率
- 有2次预约的患者:首次、第二次预约的缺席率
- 有3次预约的患者:首次、第二次、第三次预约的缺席率
- 有4次及以上预约的患者:首次、第二次、第三次预约的缺席率,以及其余预约的整体缺席率
原方法采用手动分组计算,代码冗余,以下是更简便的Base R实现方案。
简化实现代码
# 1. 排序并生成预约序号、患者总预约次数 patient_visits <- patient_visits[order(patient_visits$patient_id, patient_visits$visit_date), ] patient_visits$appt_seq <- ave(patient_visits$patient_id, patient_visits$patient_id, FUN = seq_along) patient_visits$total_appt <- ave(patient_visits$patient_id, patient_visits$patient_id, FUN = length) # 2. 对总预约次数分组:1、2、3、4+ patient_visits$group_total <- cut( patient_visits$total_appt, breaks = c(0,1,2,3,Inf), labels = c("1", "2", "3", "4+"), right = FALSE ) # 3. 对预约场次分组:4+患者的第4次及以后场次合并为"4+" patient_visits$appt_group <- with(patient_visits, ifelse(group_total == "4+" & appt_seq > 3, "4+", as.character(appt_seq))) # 4. 批量计算各分组的缺席率 results_df <- aggregate( result ~ group_total + appt_group, data = patient_visits, FUN = function(x) mean(x == "miss") ) # 5. 整理结果格式 colnames(results_df) <- c("total_appointments", "appointment_number", "miss_rate") results_df$total_appointments <- as.numeric(results_df$total_appointments) results_df <- results_df[order(results_df$total_appointments, results_df$appointment_number), ] # 查看最终结果 print(results_df)
代码说明
- 基础字段生成:用
ave替代tapply,一次性生成每个患者的预约序号和总预约次数,避免手动拆分数据框的冗余操作。 - 总预约次数分组:通过
cut函数快速将患者按总预约次数分为4个组别,无需手动筛选不同次数的患者ID。 - 场次分组合并:用
ifelse统一处理4+次预约患者的场次,自动将第4次及以后的场次合并为"4+",逻辑更简洁。 - 批量计算缺席率:使用
aggregate按总预约次数和场次分组,一次性完成所有场景的缺席率计算,替代多次手动rbind的重复代码。 - 结果格式整理:重命名列并排序,得到与原方法完全一致的输出结构。
这个方法逻辑清晰、代码简洁,且能自动适配不同的预约次数分组,扩展性更强。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

