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

基于分组的列筛选标记值偏移处理:避免组重复选中

实现分组唯一选中的R语言方案

需求说明

现有带多分组的有序数据集,selected列是系统按固定间隔标记的选中行(如示例中每4行标记一次),但需遵循核心规则:每个分组只能被选中一次。若系统标记出现同一分组多次选中的情况,需将重复的标记向下偏移,直到找到第一个未被选中过的分组,将该分组的首行标记为选中;其余符合规则的标记保持不变。

示例数据

library(tibble)
df <- tibble(group    = c(rep("A", 4), rep("B", 2), rep("C", 6), rep("D", 4), rep("E", 2), rep("F", 2)),
             selected = rep(c(NA, NA, 1, NA), times = 5))

原始数据预览:

# A tibble: 20 x 2
   group selected
   <chr>    <dbl>
 1 A           NA
 2 A           NA
 3 A            1
 4 A           NA
 5 B           NA
 6 B           NA
 7 C            1
 8 C           NA
 9 C           NA
10 C           NA
11 C            1 # 同一分组重复选中,不符合规则
12 C           NA
13 D           NA
14 D           NA
15 D            1
16 D           NA
17 E           NA
18 E           NA
19 F            1
20 F           NA

期望结果

# A tibble: 20 x 2
   group selected
   <chr>    <dbl>
 1 A           NA
 2 A           NA
 3 A            1
 4 A           NA
 5 B           NA
 6 B           NA
 7 C            1
 8 C           NA
 9 C           NA
10 C           NA
11 C           NA # 重复标记改为NA
12 C           NA
13 D           NA
14 D           NA
15 D            1
16 D           NA
17 E            1 # 转移到未被选中的E组首行
18 E           NA
19 F            1
20 F           NA

实现思路

  • 提取候选选中行:先筛选出原始selected列中值为1的行,记录它们的原始行号和对应分组,形成候选列表。
  • 区分合法与重复候选:遍历候选列表,保留每个分组的首次选中标记,将同一分组的后续标记标记为待调整项。
  • 收集未被选中的分组:从所有分组中排除已被合法选中的分组,按数据集中的出现顺序生成可用分组列表。
  • 调整重复标记位置:对每个待调整的重复标记,按顺序从可用分组列表中取出第一个分组,将该分组的首行设为选中状态,同时移除该分组的可用资格。
  • 合并生成最终数据:将合法标记和调整后的标记替换回原始数据,其余行设为NA。

代码实现参考

library(dplyr)
library(tibble)

# 1. 提取原始候选选中行的行号和分组
original_candidates <- df %>%
  mutate(row_id = seq_len(nrow(.))) %>%
  filter(selected == 1) %>%
  select(row_id, group)

# 2. 筛选合法候选(每个分组仅保留第一个选中行)
valid_candidates <- original_candidates %>%
  group_by(group) %>%
  slice(1) %>%
  ungroup()

# 3. 标记需要调整的重复候选
duplicate_candidates <- original_candidates %>%
  anti_join(valid_candidates, by = c("row_id", "group"))

# 4. 获取按原始顺序排列的未被选中分组
all_groups <- unique(df$group)
available_groups <- setdiff(all_groups, valid_candidates$group)

# 5. 生成调整后的选中行
adjusted_rows <- integer(0)
for (i in seq_len(nrow(duplicate_candidates))) {
  if (length(available_groups) == 0) break
  # 取第一个可用分组的首行行号
  target_group <- available_groups[1]
  target_row <- which(df$group == target_group)[1]
  adjusted_rows <- c(adjusted_rows, target_row)
  # 移除已使用的分组
  available_groups <- available_groups[-1]
}

# 6. 更新数据集得到最终结果
df_final <- df %>%
  mutate(row_id = seq_len(nrow(.))) %>%
  mutate(selected = case_when(
    row_id %in% valid_candidates$row_id ~ 1,
    row_id %in% adjusted_rows ~ 1,
    TRUE ~ NA_real_
  )) %>%
  select(-row_id)

# 查看结果
print(df_final)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:15:37