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

如何在R中按ID过滤掉与负值数量匹配的正值行?

解决方案

你可以通过分组计算每个ID的负值数量,再对正值行进行抽样保留指定数量的方式实现需求,最终满足nrow(df) == sum(df$count)的条件。具体代码如下:

library(tidyverse)
set.seed(1)

# 生成示例数据
df <- tibble(
  count = sample(c(-1,1),80,replace = TRUE,prob=c(.2,.8)),
  id = rep(1:4,20)
)

# 处理数据:移除所有负值行,同时移除与负值数量相等的正值行
result <- df %>%
  group_by(id) %>%
  # 计算当前ID的负值数量和需要保留的正值数量(即sum(count))
  mutate(
    neg_count = sum(count == -1),
    keep_pos = sum(count)
  ) %>%
  # 仅保留正值行
  filter(count == 1) %>%
  # 随机抽取需要保留的正值行数量(若不需要随机,可改用slice_head/slice_tail)
  slice_sample(n = first(keep_pos)) %>%
  ungroup() %>%
  # 移除辅助计算列
  select(-neg_count, -keep_pos)

# 验证条件
nrow(result) == sum(result$count) # 返回TRUE,说明满足要求

# 查看处理后每个ID的结果统计
result %>%
  group_by(id) %>%
  summarize(保留行数 = n(), count总和 = sum(count))

逻辑说明

  1. 按id分组后,统计每个组内的负值行数量neg_count,以及需要保留的正值行数量keep_pos(即该组count的总和,等于原正值数减去负值数)。
  2. 筛选出所有正值行,通过slice_sample随机抽取keep_pos行,确保保留的正值行数量恰好抵消退款后的有效计数。
  3. 最终保留的数据集仅包含未被退款抵消的正值行,行数等于count总和,完全满足nrow(df) == sum(df$count)的要求。

如果业务场景需要保留负值行(仅移除对应数量的正值行),可调整代码如下,但此时nrow(df) == sum(df$count)的条件不再成立(负值行的count为-1会拉低总和):

# 保留负值行的版本
result_with_neg <- df %>%
  group_by(id) %>%
  mutate(
    neg_count = sum(count == -1),
    keep_pos = sum(count)
  ) %>%
  # 保留所有负值行 + 指定数量的正值行
  filter(count == -1 | (count == 1 & row_number() <= keep_pos)) %>%
  ungroup() %>%
  select(-neg_count, -keep_pos)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:55:27