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

R中length(unique())替代n_distinct()的多列计数问题与传参咨询

问题原因与解决方案

问题1:length(unique(across(all_of(vars))))返回2的原因

across(all_of(vars))会返回一个包含指定列的tibble(子数据框),unique()处理这个tibble后得到的仍是一个tibble(包含该组内多列组合的唯一行)。而length()作用于tibble时,返回的是列的数量,不是唯一行的数量,所以你得到了vars的长度2,而非预期的唯一组合数。

问题2:length(unique(Sepal.Length, Petal.Width))返回15的原因

unique()函数仅接受第一个参数作为待去重的向量,后续参数会被当作函数的可选参数(比如fromLast)使用。当你传入两个变量时,Petal.Width会被强制转换为逻辑值,实际执行的是对Sepal.Length单列的去重计数——setosa组的Sepal.Length恰好有15个唯一值,所以得到15,这和多列组合的唯一计数完全无关。

解决方案:用字符向量列名实现高效多列去重计数

方式1:在dplyr管道内实现

利用cur_data()获取当前分组的数据集,通过字符向量筛选列后,用unique()获取唯一行再计数:

foo <- iris |>
  group_by(Species) |>
  mutate(
    raw_count = n(),
    adjusted_count = nrow(unique(cur_data()[vars]))
  )

对setosa组,该代码会返回预期的28。

方式2:用data.table实现更高性能(适合超大型数据集)

data.table的uniqueN()函数原生支持按指定列计数唯一组合,性能远高于n_distinct(),尤其适合大型数据集:

library(data.table)

dt <- as.data.table(iris)
foo <- dt[, .(
  raw_count = .N,
  adjusted_count = uniqueN(.SD, by = vars)
), by = Species]

# 可选:转回tibble格式
foo <- as_tibble(foo)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:01:33