在R语言中为足球比赛数据框添加shots_conceded(被射门次数)列的技术实现问询
解决方案:计算累计被射门次数(
shots_conceded) 这里有两种可行的方法,一种适配你正在使用的plyr包,另一种使用更现代的dplyr包(更推荐,因为plyr已停止维护):
方法1:使用dplyr(推荐)
这种方法更简洁通用,不需要硬编码球队名称:
library(dplyr) # 先确保数据按比赛ID和时间顺序排序 df1 <- df1 %>% arrange(game_id, minute) # 分组计算累计被射门次数 df1 <- df1 %>% group_by(game_id) %>% mutate( # 自动匹配当前行球队的对手 opponent = setdiff(unique(team_name), team_name), # 计算截至当前时间点前,对手的累计射门数 shots_conceded = lag( cumsum(type_name == "shot" & team_name == opponent), default = 0 ) ) %>% ungroup() %>% select(-opponent) # 移除临时的对手标记列
方法2:使用plyr(兼容你的现有代码)
如果你想继续沿用plyr的工作流,可以这样实现:
library(plyr) # 确保数据按比赛ID和时间排序(和你现有代码一致) df1 <- df1[with(df1, order(game_id, minute)), ] # 按比赛分组计算被射门次数 df1 <- ddply(df1, .(game_id), function(game_data) { # 获取当前比赛的两支球队 teams <- unique(game_data$team_name) # 为每一行标记对应的对手球队 game_data$opponent <- ifelse(game_data$team_name == teams[1], teams[2], teams[1]) # 计算截至当前行之前的对手累计射门数 game_data$shots_conceded <- lag( cumsum(game_data$type_name == "shot" & game_data$team_name == game_data$opponent), default = 0 ) # 移除临时列 game_data <- game_data[, !names(game_data) %in% "opponent"] return(game_data) })
关键逻辑说明
- 排序:必须先按
game_id和minute排序,保证时间线的正确性,累计计算才符合实际比赛进程; - 对手匹配:通过自动识别当前比赛的两支球队,避免硬编码球队名称,让代码更通用;
- 累计与滞后:用
cumsum计算到当前行的对手射门总数,再用lag(default=0)取当前行之前的累计值——因为当前行是本队的射门事件,被射门次数应该是这个时间点之前对手完成的射门数。
运行代码后,你会得到和示例完全一致的shots_conceded列结果。
内容的提问来源于stack exchange,提问作者WenkyWong
相关产品推荐
相关产品推荐

