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

多类别列中filter()函数无法正确过滤的问题排查

按类别移除首尾指定百分比数据的函数修正方案

问题根源

你的函数在分组过滤阶段出错,核心原因是在group_by后的filter中直接引用外部数据集summary_data$n_to_remove,无法实现每个组匹配对应类别的移除行数。summary_data是独立的汇总表,其n_to_remove是一个向量,在分组环境中无法自动与当前组绑定,导致所有组误用了向量的第一个值,逻辑完全错误。

修正方案(简洁版)

直接在分组内计算每个类别的移除行数,避免外部对象的引用问题:

remove_percentile_by_category <- function(data, measurement_column, category_column, date_column, percent_to_remove) {
  data_filtered <- data %>%
    # 按类别和指定度量列排序(确保数据顺序正确)
    arrange({{category_column}}, {{measurement_column}}) %>%
    group_by({{category_column}}) %>%
    # 分组计算当前类别需要移除的首尾行数
    mutate(n_to_remove = ceiling(n() * percent_to_remove / 100)) %>%
    # 过滤掉首尾指定行数:保留行号大于移除数,且小于等于总行数减移除数的行
    filter(row_number() > n_to_remove & row_number() <= n() - n_to_remove) %>%
    # 清理临时计算列
    select(-n_to_remove) %>%
    ungroup() %>%
    # 最终按类别和日期排序
    arrange({{category_column}}, {{date_column}})
  
  return(data_filtered)
}

验证测试

用你的数据集测试移除2%的情况:

# 加载依赖包
library(dplyr)

# 原始数据集
set.seed(3994)
val <- seq(1:60)
cat <- rep(c("A", "B", "C"), times=c(30, 20, 10))
date <- as.Date(sample(seq(as.Date('2000/01/01'), as.Date('2020/01/01'), by="day"), 60))
df <- data.frame(val, cat, date) %>% arrange(cat, val)

# 执行函数
df_filtered <- remove_percentile_by_category(df, val, cat, date, 2)

# 查看每个类别的剩余行数
df_filtered %>% count(cat)

输出结果符合预期:

cat  n
1   A 28 (30 - 1*2 = 28,30*2%=0.6,ceiling后取1)
2   B 18 (20 - 1*2 = 18,20*2%=0.4,ceiling后取1)
3   C  8 (10 - 1*2 = 8,10*2%=0.2,ceiling后取1)

备选方案(基于汇总表合并)

如果你坚持要先生成汇总表,可以通过left_join将移除行数合并到原数据,再进行过滤:

remove_percentile_by_category <- function(data, measurement_column, category_column, date_column, percent_to_remove) {
  data_sorted <- data %>%
    arrange({{category_column}}, {{measurement_column}})
  
  # 生成每个类别的汇总信息
  summary_data <- data_sorted %>%
    group_by({{category_column}}) %>%
    summarize(n = n()) %>%
    mutate(n_to_remove = ceiling(n * percent_to_remove / 100))
  
  # 将汇总信息合并到原数据
  data_merged <- left_join(
    data_sorted, 
    summary_data, 
    by = rlang::as_name(enquo(category_column))
  )
  
  # 分组过滤
  data_filtered <- data_merged %>%
    group_by({{category_column}}) %>%
    filter(row_number() > n_to_remove & row_number() <= n - n_to_remove) %>%
    select(-n, -n_to_remove) %>%
    ungroup() %>%
    arrange({{category_column}}, {{date_column}})
  
  return(data_filtered)
}

内容的提问来源于stack exchange,提问作者Joe the Second

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:16:04