R语言双重for循环填充选举人票统计向量结果全为NA的问题排查
问题根因
- 初始值错误:结果向量初始赋值为
NA,R语言中NA与任何数值做算术运算的结果都是NA,累加逻辑从第一步就失效。 - 循环维度错位:外层循环的
i对应选举日前第i天,但内层循环没有筛选DaysToEday == i的观测,无论i取何值,内层都遍历所有距选举日≤90天的记录,完全没有按天拆分计算。 - 索引不匹配:内层循环的
j是基于筛选后子集的行数,但取值时直接索引原始数据集mpres08的行,会出现行号错位、取到无关数据的问题。
修复方案
修正后的循环实现
如果你要保留双重循环的写法,先修正初始值、日期匹配逻辑和索引问题,代码如下:
# 提前提取选举日前90天的全量数据,避免循环内重复子集计算 last90 <- subset(mpres08, DaysToEday <= 90) # 结果向量初始值必须设为0,不能是NA Obama08.ECvotesByDay <- McCain08.ECvotesByDay <- rep(0, 90) for (i in 1:90) { # 先筛选出当前循环对应天数的所有州记录 current_day <- subset(last90, DaysToEday == i) # 遍历当天所有州的博彩数据计票 for (j in 1:nrow(current_day)) { if (current_day$PriceD[j] > current_day$PriceR[j]) { Obama08.ECvotesByDay[i] <- Obama08.ECvotesByDay[i] + current_day$EV[j] } else { McCain08.ECvotesByDay[i] <- McCain08.ECvotesByDay[i] + current_day$EV[j] } } }
向量化简洁实现(无循环)
你提到的ifelse()完全可以实现这个需求,R语言做分组统计不需要写显式循环,运行效率更高、逻辑更不容易出错:
# 提取选举日前90天数据 last90 <- subset(mpres08, DaysToEday <= 90) # 用ifelse标记每条观测的选举人票归属 last90$obama_ev <- ifelse(last90$PriceD > last90$PriceR, last90$EV, 0) last90$mccain_ev <- ifelse(last90$PriceD > last90$PriceR, 0, last90$EV) # 按距选举日天数分组求和,直接得到每日计票结果 daily_count <- aggregate(cbind(obama_ev, mccain_ev) ~ DaysToEday, data = last90, FUN = sum) # 补全1-90天的所有记录,无数据的天数计票填0 full_day_ref <- data.frame(DaysToEday = 1:90) daily_count <- merge(full_day_ref, daily_count, by = "DaysToEday", all.x = TRUE) daily_count[is.na(daily_count)] <- 0 # 提取最终结果向量 Obama08.ECvotesByDay <- daily_count$obama_ev McCain08.ECvotesByDay <- daily_count$mccain_ev
补充说明
- 你提供的样例数据中所有记录的
DaysToEday均大于200,不在最后90天范围内,测试时这部分数据不会进入计算属于正常情况。 - 现有逻辑将
PriceD == PriceR的平局场景的选举人票全部计入麦凯恩的总数,如果你需要单独处理平局(比如两边各分一半、弃票不计等),可以在判断条件中增加对应分支。
内容的提问来源于stack exchange,提问作者professor.luther.ratigan
相关产品推荐
相关产品推荐

