在R中处理变量生成新数据集:筛选患者用药最多药房
解决方案:为每位患者匹配取药总量最高的药房
别发愁啦,我正好能帮你解决这个问题!你需要的是按患者分组,先计算每个患者在每家药房的总取药量,再选出每个患者总药量最高的那家药房——这其实是个很典型的分组聚合+筛选问题,可能你之前用dplyr的时候步骤没串对,我给你详细的代码和优化方案:
1. 使用dplyr实现(逻辑清晰,适合入门)
dplyr的语法很直观,我们分两步走:先按「患者+药房」分组求和,再按「患者」分组筛选出总药量最大的记录:
library(dplyr) # 你的示例数据 df <- data.frame( name = c("Tom", "Rob", "Tom", "Tom", "Amy"), pharmacy = c("A", "B", "B", "B", "C"), meds = c(3, 2, 5, 8, 2) ) # 第一步:计算每个患者在各药房的总取药量 df_grouped <- df %>% group_by(name, pharmacy) %>% summarise(total_meds = sum(meds), .groups = "drop") # 第二步:为每位患者筛选出总药量最高的药房 df_final <- df_grouped %>% group_by(name) %>% filter(total_meds == max(total_meds)) %>% ungroup() # 查看结果 print(df_final)
运行后会得到你期望的结果:
# A tibble: 3 × 3 name pharmacy total_meds <chr> <chr> <dbl> 1 Amy C 2 2 Rob B 2 3 Tom B 13
处理平局情况
如果有患者在多家药房的总取药量相同,上面的代码会保留所有符合条件的记录。如果你只想保留其中一条(比如第一条),可以在filter后加上slice_head(n = 1):
df_final_single <- df_grouped %>% group_by(name) %>% filter(total_meds == max(total_meds)) %>% slice_head(n = 1) %>% # 只保留每个患者的第一个最高量药房 ungroup()
2. 使用data.table实现(针对大数据优化,速度更快)
你的数据集有2400万行,dplyr可能会有点慢,data.table是处理大数据的绝佳选择——它的内存占用更低、运算速度更快,非常适合这种大规模数据集:
library(data.table) # 转换为data.table格式(或者直接用fread读取原始数据,比read.csv快很多) setDT(df) # 一步完成分组求和+筛选最高量药房 dt_final <- df[, .(total_meds = sum(meds)), by = .(name, pharmacy)][ , .SD[total_meds == max(total_meds)], by = name ] # 如果要处理平局,只保留第一条: dt_final_single <- df[, .(total_meds = sum(meds)), by = .(name, pharmacy)][ , .SD[which.max(total_meds)], by = name ] # 查看结果 print(dt_final)
大数据读取建议
如果你的原始数据是CSV等格式,推荐用data.table的fread()函数读取,比base R的read.csv()快几十倍:
# 读取大规模数据集 df <- fread("your_large_dataset.csv")
内容的提问来源于stack exchange,提问作者AlexM
相关产品推荐
相关产品推荐

