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

如何用tidyverse高效筛选分组内无重复值的列并精简数据集

高效精简混合格式数据集的tidyverse单管道方案

问题背景

我有一个混合长/短格式的大型数据集:部分列按id和visit分组后值唯一,另一部分列每组内有多个值。短格式数据为匹配长格式被重复填充,导致出现大量重复行。已有的筛选精简方案运行速度较慢,需要一个基于tidyverse的高效单管道解决方案。

示例数据生成

library(tidyverse)

n_id = 200
n_visit = 15
r = 20
N = n_id*n_visit*r
df = tibble(
  id=rep(1:n_id, each=n_visit*r),
  visit=rep(paste0("v", 1:n_visit), times=n_id*r),
) %>% 
  mutate(
    !!!set_names(rep(NA, 50), paste0("short",1:50)),
    !!!set_names(rep(NA, 50), paste0("long",1:50)),
    across(starts_with("short"), ~visit),
    across(starts_with("long"), ~rnorm(n())),
) %>% 
  arrange(id, visit)

# 验证列特性:short列每组唯一,long列每组多值
df %>% summarise(a=n_distinct(short1), .by=c(id, visit)) %>% pull() %>% unique()
#> [1] 1
df %>% summarise(a=n_distinct(long1), .by=c(id, visit)) %>% pull() %>% unique()
#> [1] 20

高效单管道解决方案

df %>%
  group_by(id, visit) %>%
  summarise(
    # 对每列:如果组内唯一则保留该值,否则标记为NA
    across(everything(), ~if(n_distinct(.x) == 1) first(.x) else NA),
    .groups = "drop"  # 分组后自动取消分组
  ) %>%
  # 筛选掉全为NA的列(即原数据中每组多值的列)
  select(where(~!all(is.na(.x)))) %>%
  # 确保无重复行(分组汇总后已基本无重复,此步为冗余保障)
  distinct()

方案优势

  • 速度优化:使用n_distinct()替代length(unique(.x)),n_distinct针对tidyverse分组场景做了性能优化,计算更快
  • 单管道完成:无需创建中间变量,减少内存占用与数据拷贝开销
  • 一步到位:在分组汇总阶段直接完成值提取与无效列标记,后续仅需筛选有效列即可得到目标数据集

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:27:09