You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:50:29