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

dplyr分组筛选优化:优先保留现任者+最高得票候选人

问题:分组筛选候选人时优先保留现任者

现有R语言dplyr代码,按城市(nm_municipio)和州(sg_uf)分组后,从candidates2024数据框中筛选每组得票最高的2位候选人:

candidates2024 <- candidates2024 %>%
  group_by(nm_municipio, sg_uf) %>%  # 按城市和州分组
  slice_max(order_by = qt_votos_nom_validos, n = 2) %>%  # 选取每组得票前2的候选人
  ungroup()

需加入incumbent变量的逻辑:该虚拟变量为1时表示候选人是上届当选者,为0则不是。具体规则:

  • 若分组内存在现任者,需让其自动占据一个名额,另一个名额分配给剩余候选人中得票最高者;
  • 若分组内无现任者,则按原逻辑执行。

当前代码会剔除得票第三但为现任者的Tiago Dias,期望保留他和得票最高的Valdice。

数据的dput如下:

structure(list(sg_uf = c("BA", "BA", "BA", "BA", "BA", "BA"), 
nm_municipio = c("JACARACI", "JACARACI", "JACOBINA", "JACOBINA", 
"JACOBINA", "JACOBINA"), cd_cargo = c(11L, 11L, 11L, 11L, 
11L, 11L), ds_cargo = c("Prefeito", "Prefeito", "Prefeito", 
"Prefeito", "Prefeito", "Prefeito"), nr_candidato = c(40L, 
55L, 35L, 40L, 65L, 50L), nm_candidato = c("DEUSDEDIT CARVALHO ROCHA", 
"HANNEY LADEIA SOARES FLORES", "VALDICE CASTRO VIEIRA DA SILVA", 
"MARIANA MATOS DE OLIVEIRA", "TIAGO MANOEL DIAS FERREIRA", 
"VALESSIO SOARES DE BRITO"), nm_urna_candidato = c("DETINHO", 
"HANNEY LADEIA", "VALDICE", "MARIANA OLIVEIRA", "TIAGO DIAS", 
"VALESSIO FILHO DE JACOBINA"), sg_partido = c("PSB", "PSD", 
"PMB", "PSB", "PC do B", "PSOL"), ds_composicao_coligacao = c("Federação BRASIL DA ESPERANÇA - FE BRASIL(PT/PC do B/PV) / AGIR / PSB", 
"PP / PSD", "REPUBLICANOS / PP / PDT / PL / PRD / DC / PMB / SOLIDARIEDADE", 
"AVANTE / Federação PSDB CIDADANIA(PSDB/CIDADANIA) / PSB", 
"PRTB / PSD / MOBILIZA / MDB / AGIR / PODE / Federação BRASIL DA ESPERANÇA - FE BRASIL(PT/PC do B/PV)", 
"Federação PSOL REDE(PSOL/REDE)"), nr_turno = c(1L, 1L, 
1L, 1L, 1L, 1L), ds_sit_totalizacao = c("Eleito", "Não Eleito", 
"Eleito", "Não Eleito", "Não Eleito", "Não Eleito"), dt_ult_totalizacao = c("2024-10-06 20:25:25", 
"2024-10-06 20:25:25", "2024-10-06 20:08:52", "2024-10-06 20:08:52", 
"2024-10-06 20:08:52", "2024-10-06 20:08:52"), sg_ue = c(36498L, 
36498L, 36510L, 36510L, 36510L, 36510L), sq_candidato = c(50002150514, 
50002002442, 50002347768, 50002074476, 50002074352, 50002074411
), nm_tipo_destinacao_votos = c("Válido", "Válido", "Válido", 
"Válido", "Válido", "Válido"), sq_eleicao_divulga = c(2045202024L, 
2045202024L, 2045202024L, 2045202024L, 2045202024L, 2045202024L
), aa_eleicao = c(2024L, 2024L, 2024L, 2024L, 2024L, 2024L
), nm_regiao = c("NORDESTE", "NORDESTE", "NORDESTE", "NORDESTE", 
"NORDESTE", "NORDESTE"), pc_votos_validos = c(0.5092, 0.4908, 
0.4686, 0.3296, 0.1921, 0.0097), qt_votos_nom_validos = c(4804L, 
4630L, 21952L, 15444L, 9000L, 454L), qt_votos_concorrentes = c(9434L, 
9434L, 46850L, 46850L, 46850L, 46850L), incumbent = c(0, 
0, 0, 0, 1, 0), ranLastElection = c(0, 0, 0, 1, 1, 0)), row.names = 1088:1093, class = "data.frame")

解决方案

使用dplyr的分组逻辑结合条件筛选实现需求:

candidates2024 <- candidates2024 %>%
  group_by(nm_municipio, sg_uf) %>%
  # 分两部分筛选后合并:现任者 + 非现任得票最高者
  bind_rows(
    # 筛选所有现任者
    filter(., incumbent == 1),
    # 筛选非现任者,取(2 - 现任者数量)位得票最高的
    filter(., incumbent == 0) %>%
      slice_max(order_by = qt_votos_nom_validos, n = max(0, 2 - sum(incumbent == 1)))
  ) %>%
  ungroup()

逻辑说明

  • 分组后,首先提取所有incumbent=1的候选人,确保他们被保留;
  • 计算每组需要从非现任者中选取的人数:2 - 现任者数量,如果没有现任者则取2位,有1位现任则取1位;
  • 从非现任者中按得票降序选取对应数量的候选人;
  • 将两部分结果合并,最后取消分组。

测试该代码后,JACOBINA分组会保留Valdice(得票最高的非现任)和Tiago Dias(现任者),符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:34:54