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

如何在单条dplyr管道中两次调用distinct等函数完成数据聚合

单管道实现方案

你不需要拆分数据集生成df1/df2两个中间变量,也不需要在distinct()后恢复原始数据,核心思路是提前在原始数据集上标记不同去重规则下的保留行,再一次性完成分组汇总,全程可以在单条管道内跑完,无重复代码。

最简实现(无额外依赖,和原代码输出完全一致)

直接用duplicated()标记两个去重规则对应的保留行,分组后分别计算均值即可:

library(dplyr)

final_result <- iris %>%
  mutate(
    # 标记distinct(Species, .keep_all = TRUE)对应的保留行
    keep_for_mean1 = !duplicated(Species),
    # 标记distinct(Species, Petal.Width, .keep_all = TRUE)对应的保留行
    keep_for_mean2 = !duplicated(paste(Species, Petal.Width))
  ) %>%
  group_by(Petal.Width) %>%
  summarise(
    Sepal.Length.mean1 = mean(Sepal.Length[keep_for_mean1]),
    Sepal.Length.mean2 = mean(Sepal.Length[keep_for_mean2]),
    .groups = "drop"
  )

这个写法全程不会修改原始数据集的行,只是给行加了逻辑标记,自然不存在distinct()后无法恢复初始数据的问题,代码重复度为0,可读性也比拆分中间表更高。

多规则扩展写法

如果后续需要新增更多不同去重粒度的汇总逻辑,可以用列表批量传入去重规则,自动处理后合并结果,同样全程单管道:

library(dplyr)
library(purrr)

final_result <- list(
  mean1 = "Species",
  mean2 = c("Species", "Petal.Width")
) %>%
  imap(~{
    iris %>%
      distinct(across(all_of(.x)), .keep_all = TRUE) %>%
      group_by(Petal.Width) %>%
      summarise("Sepal.Length.{.y}" := mean(Sepal.Length), .groups = "drop")
  }) %>%
  reduce(inner_join, by = "Petal.Width")

这个写法适合3种及以上去重规则的场景,如果只有2种规则,优先用第一种标记法,逻辑更直观。

内容的提问来源于stack exchange,提问作者monotonic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:39:39