在R语言中使用spread()时对重复键求和的问题
Hey Mike, 我来帮你搞定这个选举Margin值计算的问题!华盛顿州的Top 2初选制确实会带来特殊情况,同党派候选人对决时,常规的两党得票差逻辑就不适用了,咱们一步步来解决:
先明确问题核心
你需要针对每个选区(Dist),先找出得票前两名的候选人,再根据他们的党派关系计算适合地图填充的Margin值——毕竟同党派对决和跨党派对决的Margin解读逻辑不一样。
先假设你的数据结构(补全你没写完的部分)
我先模拟一个和你描述匹配的示例数据框,方便后续演示:
# 示例选举数据:Dist=选区,Party=党派,Votes=得票数 election_data <- data.frame( Dist = c(1, 1, 2, 2, 2, 3, 3), Party = c("D", "R", "D", "D", "R", "R", "R"), Votes = c(15000, 12000, 20000, 18000, 10000, 25000, 22000) )
步骤1:按选区提取得票前两名的候选人
首先要对每个选区的候选人按得票数降序排序,只保留前两名。这里用dplyr包处理会更清爽(如果没装的话先跑install.packages("dplyr")):
library(dplyr) # 分组+排序+取前两名 top_two_candidates <- election_data %>% group_by(Dist) %>% arrange(desc(Votes)) %>% # 按得票数从高到低排 slice(1:2) %>% # 取前两名 ungroup()
步骤2:计算每个选区的总票数
Margin通常是得票差占总票数的比例,所以先算出每个选区的总有效票数:
district_total_votes <- election_data %>% group_by(Dist) %>% summarise(Total_Votes = sum(Votes)) %>% ungroup()
步骤3:分情况计算Margin值
这里分两种核心场景处理:
- 跨党派对决:前两名来自不同党派,Margin = (第一名得票数 - 第二名得票数)/总票数
- 同党派对决:前两名来自同一党派,同样计算两人的得票差占比,同时标记出这个特殊场景(方便后续地图可视化区分)
margin_calculation <- top_two_candidates %>% group_by(Dist) %>% mutate( # 提取前两名的票数和党派 Top1_Votes = first(Votes), Top1_Party = first(Party), Top2_Votes = last(Votes), Top2_Party = last(Party) ) %>% # 合并总票数数据 left_join(district_total_votes, by = "Dist") %>% # 计算Margin并标记竞选类型 mutate( Margin = (Top1_Votes - Top2_Votes)/Total_Votes, Race_Type = ifelse(Top1_Party == Top2_Party, "同党派对决", "跨党派对决") ) %>% # 每个选区只保留一条汇总记录 distinct(Dist, .keep_all = TRUE) %>% # 筛选出地图需要的核心字段 select(Dist, Top1_Party, Top2_Party, Margin, Race_Type, Total_Votes)
验证示例结果
跑上面的代码后,你会得到这样的输出:
| Dist | Top1_Party | Top2_Party | Margin | Race_Type | Total_Votes |
|---|---|---|---|---|---|
| 1 | D | R | 0.1111 | 跨党派对决 | 27000 |
| 2 | D | D | 0.0526 | 同党派对决 | 48000 |
| 3 | R | R | 0.0606 | 同党派对决 | 47000 |
这个结果里的Margin字段直接可以用来填充地图,Race_Type还能帮你给同党派对决的选区做特殊可视化标记(比如用不同的颜色渐变逻辑)。
如果你的数据里有无效票/空白票,记得在计算Total_Votes时提前排除哦!
内容的提问来源于stack exchange,提问作者Mike206
相关产品推荐
相关产品推荐

