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

R语言如何提取数据框同一因子水平前序观测生成球队赛事状态列

足球赛事状态列实现方案

你的需求核心是:按时间顺序的赛事表中,为每场比赛的主队、客队分别匹配该队上一场的赛果(胜W/平D/负L),写入HomeForm和AwayForm列。以下是R中两种可直接落地的实现方式,解决你提到的“定位特定球队历史观测、提取对应信息”的核心问题。


基础R实现(无额外包依赖)

注:你提供的示例数据中Result字段长度(15)短于主客队字段长度(30),示例代码会自动兼容长度差,保证可直接运行。

  1. 先为每条比赛记录拆分主队、客队的单场赛果:Result = "H"代表主队胜、"A"代表客队胜、"D"代表平局
  2. 将单场双队的记录拆成逐队的长表,按球队、比赛时间排序
  3. 按球队分组,将赛果滞后1位,即为当前比赛对应的球队上一场状态
  4. 将状态值映射回原赛事表的主、客队列
# 补全Result字段长度适配原示例数据
Result <- c("H","H","D","A","H","A","H","D","H","A","A","H","D","A","A",
            "H","D","A","H","D","A","H","D","H","A","A","H","D","A","L")
HomeTeam <- c("Liverpool", "ManCity", "ManUnited", "Tottenham", "Arsenal", "Leicester", "Chelsea", "Leeds", "Liverpool", "ManCity", "ManUnited", "Tottenham", "Arsenal", "Leicester", "Chelsea","Liverpool", "ManCity", "ManUnited", "Tottenham", "Arsenal", "Leicester", "Chelsea", "Leeds", "Liverpool", "ManCity", "ManUnited", "Tottenham", "Arsenal", "Leicester", "Chelsea")
AwayTeam <- c("Chelsea", "Tottenham", "Arsenal", "ManUnited", "Leicester", "ManCity", "Leeds", "Chelsea", "Leicester", "Liverpool", "Arsenal", "ManUnited", "Tottenham", "ManCity", "Liverpool","Chelsea", "Tottenham", "Arsenal", "ManUnited", "Leicester", "ManCity", "Leeds", "Chelsea", "Leicester", "Liverpool", "Arsenal", "ManUnited", "Tottenham", "ManCity", "Liverpool")
data <- data.frame(HomeTeam, AwayTeam, Result)

# 计算主、客队单场赛果
data$home_res <- ifelse(data$Result == "H", "W", ifelse(data$Result == "D", "D", "L"))
data$away_res <- ifelse(data$Result == "A", "W", ifelse(data$Result == "D", "D", "L"))

# 构造逐队的长格式比赛记录
home_tbl <- data.frame(team = data$HomeTeam, game_idx = seq(nrow(data)), res = data$home_res)
away_tbl <- data.frame(team = data$AwayTeam, game_idx = seq(nrow(data)), res = data$away_res)
team_long <- rbind(home_tbl, away_tbl)
team_long <- team_long[order(team_long$team, team_long$game_idx), ]

# 按球队分组,取上一场的赛果(滞后1位)
team_long$last_res <- ave(
  team_long$res,
  team_long$team,
  FUN = function(x) c(NA, head(x, -1)) # 首次参赛的球队无历史记录,用NA占位
)

# 将上一场状态映射回原表的主、客队列
data$HomeForm <- mapply(
  function(t, idx) team_long$last_res[team_long$team == t & team_long$game_idx == idx],
  data$HomeTeam, seq(nrow(data))
)
data$AwayForm <- mapply(
  function(t, idx) team_long$last_res[team_long$team == t & team_long$game_idx == idx],
  data$AwayTeam, seq(nrow(data))
)
  • 核心逻辑说明:如果需要手动定位某支球队的历史记录,可直接用子集匹配语法:比如取利物浦的所有比赛记录就是team_long[team_long$team == "Liverpool", ],取最早的1条历史记录用head(..., 1)即可;逐组滞后的写法比手动逐行匹配的效率高很多,尤其适合大批量赛事数据。

tidyverse实现(逻辑更简洁,适合大表)

用dplyr、tidyr的内置函数实现相同逻辑,代码可读性更强:

library(dplyr)
library(tidyr)

data |> 
  # 计算主客队单场赛果,给每条比赛标记时间序号
  mutate(
    home_res = case_when(Result == "H" ~ "W", Result == "D" ~ "D", Result == "A" ~ "L"),
    away_res = case_when(Result == "A" ~ "W", Result == "D" ~ "D", Result == "H" ~ "L"),
    game_idx = row_number()
  ) |> 
  # 拆成逐队的长格式记录
  pivot_longer(
    cols = c(HomeTeam, AwayTeam),
    names_to = "team_type",
    values_to = "team"
  ) |> 
  # 匹配每条逐队记录对应的赛果
  mutate(res = ifelse(team_type == "HomeTeam", home_res, away_res)) |> 
  # 按球队分组,取上一场的赛果(滞后1位)
  group_by(team) |> 
  arrange(game_idx, .by_group = T) |> 
  mutate(last_res = lag(res)) |> 
  ungroup() |> 
  # 转回宽表,提取主、客队的上一场状态
  pivot_wider(
    id_cols = game_idx,
    names_from = team_type,
    values_from = last_res
  ) |> 
  # 合并回原表的全部字段
  left_join(data, by = "game_idx")
  • 扩展说明:如果需要取前2场的状态做累计统计,只需把lag(res)调整为取前2条的聚合逻辑即可;首次参赛的球队返回NA值,可通过replace_na()替换为"TBD"这类默认标记。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 14:24:05