如何在R中为2021 MLB赛季数据集计算球队胜率
解决MLB赛季数据的胜场标记与球队胜率计算问题
1. 正确标记胜场(1)与负场(0)
你用ifelse只得到全1的结果,大概率是列名引用错误(比如列名带空格没加反引号、拼写错误),或者条件逻辑搞反了。以下是正确写法:
Base R 写法
假设你的数据集名为mlb_data,球队得分列是team_runs,对手得分列是opponent_runs:
# 添加胜场标记列 mlb_data$win <- ifelse(mlb_data$team_runs > mlb_data$opponent_runs, 1, 0)
如果列名带中文空格(比如球队得分),要用反引号包裹列名:
mlb_data$win <- ifelse(mlb_data$`球队得分` > mlb_data$`对手得分`, 1, 0)
排查问题点
- 检查列名:用
colnames(mlb_data)确认列名拼写和格式 - 验证条件逻辑:取几行数据手动对比,比如
head(mlb_data[, c("球队得分", "对手得分")]),看是否真的所有比赛都是球队得分更高
2. 按球队(每162行)计算单独胜率
如果你的数据是每个球队连续排列162行,可以按行数分组计算;但更稳妥的是如果数据里有球队ID/名称列,直接按球队分组(避免数据顺序打乱导致错误)。
情况1:按每162行分组(数据严格按球队连续排列)
Base R 实现
# 拆分数据为每162行一组 team_groups <- split(mlb_data, rep(1:(nrow(mlb_data)/162), each = 162)) # 计算每个球队的胜率(胜场数/总比赛数) win_rates <- sapply(team_groups, function(group) mean(group$win)) # 转为数据框方便查看 team_win_rates <- data.frame(team_group = names(win_rates), win_rate = round(win_rates, 3))
Tidyverse(dplyr)实现
library(dplyr) team_win_rates <- mlb_data %>% # 创建分组标记:每162行一个球队 mutate(team_group = gl(n()/162, 162)) %>% group_by(team_group) %>% summarise( total_games = n(), total_wins = sum(win), win_rate = round(total_wins / total_games, 3) ) %>% ungroup()
情况2:用球队列分组(更可靠)
如果你的数据里有team_name或team_id列,直接按球队分组,无需依赖行数:
library(dplyr) team_win_rates <- mlb_data %>% mutate(win = ifelse(`球队得分` > `对手得分`, 1, 0)) %>% group_by(team_name) %>% summarise( total_games = n(), total_wins = sum(win), win_rate = round(total_wins / total_games, 3) ) %>% ungroup()
注意事项
- 检查数据完整性:确保总行数是162的整数倍(30支球队×162场=4860行),如果不是,说明有缺失或多余数据,需要先清洗
- 平局处理:MLB常规赛极少平局,如果存在平局,可根据需求将平局标记为0.5或单独处理,比如:
mlb_data$win <- case_when( mlb_data$`球队得分` > mlb_data$`对手得分` ~ 1, mlb_data$`球队得分` < mlb_data$`对手得分` ~ 0, TRUE ~ 0.5 # 平局按0.5计算 )
内容的提问来源于stack exchange,提问作者Marc Stern
相关产品推荐
相关产品推荐

