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

如何在R中对分组数据框的多列计算唯一值数量

一次分组完成多维度统计需求

原始数据

首先构造目标数据框:

v_1 <- c("1a", "1b","1c", "2a", "2b", "2c", "3a", "3b","3c", "4a", "4b", "4c")
v_2 <- c(1,1,1,2,2,2,3,3,3,4,4,4)
v_3 <- c("dog", "dog", "dog", "dog", "dog", "dog", "cat", "cat", "cat", "cat", "cat", "cat")
v_4 <- c(1:12)

df <- data.frame(v_1, v_2, v_3, v_4)

数据框输出如下:

v_1 v_2 v_3 v_4
1   1a   1 dog   1
2   1b   1 dog   2
3   1c   1 dog   3
4   2a   2 dog   4
5   2b   2 dog   5
6   2c   2 dog   6
7   3a   3 cat   7
8   3b   3 cat   8
9   3c   3 cat   9
10  4a   4 cat  10
11  4b   4 cat  11
12  4c   4 cat  12

原有实现方式

仅统计v_1数量时,一次分组即可完成:

library(dplyr)

df_grouped <- df %>% 
  group_by(v_3) %>% 
  summarise(v_4_sum = sum(v_4), 
            v_1_count = n())

输出结果:

v_3   v_4_sum v_1_count
  <chr>   <int>     <int>
1 cat        57         6
2 dog        21         6

但要同时统计v_2的唯一值数量时,原有方法需要两次分组:

df_grouped_v2 <- df %>% 
  group_by(v_2, v_3) %>% 
  summarise(v_4_sum = sum(v_4), 
            v_1_count = n())

df_grouped_v22 <- df_grouped_v2 %>% 
  group_by(v_3) %>% 
  summarise(v_4_sum = sum(v_4_sum), 
            v_1_count = sum(v_1_count), 
            v_2_count = n())

最终结果:

v_3   v_4_sum v_1_count v_2_count
      <chr>   <int>     <int>     <int>
    1 cat        57         6         2
    2 dog        21         6         2

一次分组的优化方案

使用dplyr中的n_distinct()函数,直接在单次分组的summarise步骤中统计v_2的唯一值数量,无需多次分组:

df_grouped_optimized <- df %>% 
  group_by(v_3) %>% 
  summarise(
    v_4_sum = sum(v_4),
    v_1_count = n(),
    v_2_count = n_distinct(v_2)
  )

运行后输出结果与两次分组的结果完全一致:

v_3   v_4_sum v_1_count v_2_count
  <chr>   <int>     <int>     <int>
1 cat        57         6         2
2 dog        21         6         2

说明

n_distinct()函数的作用是统计分组内指定列的唯一值个数,直接在按v_3分组的层级就能计算出每个v_3分组下v_2的唯一值数量,避免了多次分组带来的冗余操作,在处理大型数据框时能有效提升效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:47:46