R语言按时间点分组统计符合条件观测数 无观测补0实现方法
问题描述
我有如下结构的数据集:
id <- c(rep(1,3), rep(2, 3), rep(3, 3)) condition <- c(0, 0, 1, 0, 0, 1, 1, 1, 0) time_point1 <- c(1, 1, NA) time_point2 <- c(NA, 1, NA) time_point3 <- c(NA, NA, NA) time_point4 <- c(1, NA, NA, 1, NA, NA, NA, NA, 1) data <- data.frame(id, condition, time_point1, time_point2, time_point3, time_point4) data
数据集打印结果:
id condition time_point1 time_point2 time_point3 time_point4 1 1 0 1 NA NA 1 2 1 0 1 1 NA NA 3 1 1 NA NA NA NA 4 2 0 1 NA NA 1 5 2 0 1 1 NA NA 6 2 1 NA NA NA NA 7 3 1 1 NA NA NA 8 3 1 1 1 NA NA 9 3 0 NA NA NA 1
需求是生成统计表格,分别统计每个time_point下满足condition == 1的观测数(记为n_x),以及对应时间点的总观测数(记为n_t),无对应观测时统计值显示为0。
最初尝试的统计代码如下:
data %>% pivot_longer(cols = contains("time_point")) %>% filter (!is.na(value)) %>% group_by(name) %>% mutate(n_t = n_distinct(id)) %>% ungroup() %>% filter(condition == 1) %>% group_by(name) %>% summarise(n_x = n_distinct(id), n_t = first(n_t))
运行输出结果不符合预期:
name n_x n_t <chr> <int> <int> 1 time_point1 1 3 2 time_point2 1 3
预期输出:需要覆盖所有时间点(包含无符合条件观测的时间点),结果如下:
name n_x n_t 1 time_point1 2 6 2 time_point2 1 3 3 time_point3 0 0 4 time_point4 0 3
问题原因
原代码存在两处逻辑错误:
- 统计总观测数
n_t时错误使用n_distinct(id)按id去重计数,实际n_t是对应时间点下非NA的行总数,不需要按id去重 - 提前过滤非NA值、再过滤
condition == 1的操作,会直接丢弃没有符合条件观测的时间点分组,导致这类时间点无法出现在最终结果中,无法自动补0
正确实现方法
直接在分组汇总步骤同时计算两个统计指标即可,不需要提前过滤行,逻辑更简洁也不会遗漏分组:
library(dplyr) library(tidyr) data %>% pivot_longer(cols = starts_with("time_point"), names_to = "name") %>% group_by(name) %>% summarise( n_t = sum(!is.na(value)), n_x = sum(!is.na(value) & condition == 1), .groups = "drop" )
运行输出结果与预期完全一致:
# A tibble: 4 × 3 name n_t n_x <chr> <int> <int> 1 time_point1 6 2 2 time_point2 3 1 3 time_point3 0 0 4 time_point4 3 0
内容的提问来源于stack exchange,提问作者SaveTheDream
相关产品推荐
相关产品推荐

