按周聚合数据行:污水检测列取平均,住院列取总和
问题描述
我有一组数据,每周有多条污水中SARS-CoV-2检测记录,但每周仅有1条有效住院数据。数据按采集日期分行,包含week列。需要按周聚合行:
- 污水检测站点的数值取平均值(多数周有2条记录,部分为1或3条)
- 住院数据保留每周的最终值(实际需求为取总和,因每周仅一条有效数据,总和等于该值)
当前数据示例
week <- c(1,1,1,2,2,3) date <- c(1,2,3,4,5,6) site_a <- c(1,2,2,4,2,7) site_b <- c(4,2,3,1,2,5) hosp <- c(0,0,3,0,2,4) df <- data.frame(week, date, site_a, site_b, hosp)
数据展示:
week date site_a site_b hosp 1 1 1 1 4 0 2 1 2 2 2 0 3 1 3 2 3 3 4 2 4 4 1 0 5 2 5 2 2 2 6 3 6 7 5 4
期望结果
Week SiteA SiteB Hosp 1 1 1.667 3 3 2 2 3.000 1.5 2 3 3 7.000 5 4
尝试过的错误方法
使用group_by+summarise_all(mean)会把住院数据也取平均,不符合需求:
df %>% group_by(week) %>% summarise_all(funs(mean))
输出结果:
# A tibble: 3 × 5 week date site_a site_b hosp <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 2 1.67 3 1 2 2 4.5 3 1.5 1 3 3 6 7 5 4
解决方案
方法1:单独指定列的处理逻辑
直接在summarise中明确检测站点列取平均,住院列取总和:
library(dplyr) df %>% group_by(week) %>% summarise( SiteA = mean(site_a), SiteB = mean(site_b), Hosp = sum(hosp) ) %>% rename(Week = week)
输出结果与期望一致:
# A tibble: 3 × 4 Week SiteA SiteB Hosp <dbl> <dbl> <dbl> <dbl> 1 1 1.67 3 3 2 2 3 1.5 2 3 3 7 5 4
方法2:批量处理同类型列
如果检测站点列数量较多,用across批量匹配需要取平均的列,单独处理住院数据:
df %>% group_by(week) %>% summarise( across(starts_with("site_"), mean), # 匹配所有以site_开头的列 Hosp = sum(hosp) ) %>% rename(Week = week, SiteA = site_a, SiteB = site_b)
方法3:取住院数据的有效记录值
若每周最后一行的住院数据为有效值,也可以用last()或max()直接提取(前提是无效值为0):
df %>% group_by(week) %>% summarise( SiteA = mean(site_a), SiteB = mean(site_b), Hosp = last(hosp) ) %>% rename(Week = week)
内容的提问来源于stack exchange,提问作者James Montavon
相关产品推荐
相关产品推荐

