基于ua分组,计算ing与egr状态下fam和spp的数量差值
问题描述
示例数据框:
df <- data.frame(status = c(rep("egr", 5), rep("ing", 5)), ua = c(1, 1, 1, 1, 1, 1, 1, 1, 2, 2), fam = c(rep("fam1", 2), rep("fam2", 7), "fam3"), spp = c(rep("spp1", 3), rep("spp2", 3), "rep4", "rep5", rep("spp6", 2)))
需求:按ua列分组,使用summarise计算两种status(ing、egr)下,fam和spp的唯一值数量差(ing的数量减去egr的数量)。当前无法实现先按status提取对应fam和spp名称再汇总计算的操作。
期望输出:
output <- data.frame(ua = c(1, 2), fam = c(-1, 2), spp = c(1, 1))
计算逻辑:
- ua=1时,fam差值为-1:egr包含fam1、fam2(共2个唯一值),ing仅包含fam2(共1个唯一值),1-2=-1;
- ua=2时,无egr数据,fam差值为ing的唯一值数量2;
- ua=1时,spp差值为1:egr包含spp1、spp2(共2个唯一值),ing包含spp2、rep4、rep5(共3个唯一值),3-2=1;
- ua=2时,无egr数据,spp差值为ing的唯一值数量1。
解决方案
方法一:先分组统计再转宽计算差值
通过先按ua和status分组统计唯一值数量,转换为宽格式后计算差值:
library(dplyr) library(tidyr) df %>% group_by(ua, status) %>% summarise( fam_n = n_distinct(fam), spp_n = n_distinct(spp), .groups = "drop" ) %>% pivot_wider( id_cols = ua, names_from = status, values_from = c(fam_n, spp_n), values_fill = 0 # 缺失对应status时用0填充 ) %>% mutate( fam = fam_n_ing - fam_n_egr, spp = spp_n_ing - spp_n_egr ) %>% select(ua, fam, spp)
方法二:在summarise中直接计算差值
无需转宽,直接在分组后的summarise中分别筛选status计算唯一值数量差:
library(dplyr) df %>% group_by(ua) %>% summarise( fam = n_distinct(fam[status == "ing"]) - n_distinct(fam[status == "egr"]), spp = n_distinct(spp[status == "ing"]) - n_distinct(spp[status == "egr"]), .groups = "drop" )
两种方法均可得到符合要求的输出结果。
内容的提问来源于stack exchange,提问作者hiperhiper
相关产品推荐
相关产品推荐

