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

R语言按ID统计唯一分类属性计数的频率分布实现方法

解决方案

原代码错误原因

原有dplyr代码的summarise步骤中,length(manufacturer) >0仅判断当前ID下是否存在记录,所有分组都会返回TRUE,既没有做厂商去重,也没有统计唯一值数量,因此最终仅返回总ID个数,不符合需求。


方法1:dplyr 实现(适配中小规模数据)

代码自动识别数据中单个ID对应的最大厂商数量,自动补全中间计数为0的项,无需硬编码上限:

library(dplyr)
library(tidyr)

df %>%
  group_by(ID) %>%
  # 计算每个ID对应的去重后厂商数量
  summarise(count_manuf = n_distinct(manufacturer), .groups = "drop") %>%
  # 统计每个厂商数对应的ID个数
  count(count_manuf, name = "count_ID") %>%
  # 补全从最小厂商数到最大厂商数之间缺失的项,缺失值填0
  complete(
    count_manuf = seq(min(count_manuf), max(count_manuf)),
    fill = list(count_ID = 0)
  )

运行输出完全匹配预期格式:

# A tibble: 4 × 2
  count_manuf count_ID
        <int>    <int>
1           1        1
2           2        1
3           3        0
4           4        2

方法2:data.table 实现(适配百万行大规模数据)

针对百万行级数据集,data.table的运行速度和内存占用表现远优于dplyr,代码如下:

library(data.table)
# 将数据框转为data.table格式
setDT(df)

# 第一步:按ID分组统计去重后的厂商数量
id_count <- df[, .(count_manuf = uniqueN(manufacturer)), by = ID]
# 第二步:自动获取最大厂商数,生成完整序列,补全0计数
max_n <- max(id_count$count_manuf)
result <- data.frame(
  count_manuf = 1:max_n,
  count_ID = tabulate(id_count$count_manuf, nbins = max_n)
)

注:这里用内置的tabulate()函数做频率统计,比循环判断的效率高一个量级,百万行数据可以在毫秒级完成计算。


关键注意点

  • 统计分组内唯一值数量不要直接用length(),该函数仅返回分组总行数,不会做去重;dplyr用n_distinct()、data.table用uniqueN()实现去重计数
  • 所有统计上限均通过数据实际计算得到的最大值自动生成,不需要提前硬编码,适配任意取值范围
  • 若不需要补全计数为0的项,删掉complete()(dplyr版)或生成完整序列的步骤即可,直接返回有计数的结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 20:48:28