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

R语言补全数据集缺失年份行 统计F1车手各年累计夺冠数

F1车手累计夺冠赛季数补全方案(dplyr实现)

问题场景

  • 运行环境:R语言,使用jsonlite包调用Ergast API采集1950年至今的F1积分榜数据,已完成基础数据清洗
  • 现有进展:已完成夺冠车手的初步累计值计算,但目前数据集仅保留了车手夺冠赛季的记录,缺少非夺冠赛季、非夺冠车手的对应行
  • 目标需求:转换数据集,保证每个赛季、每位车手都有对应的cum_seasons_won(累计夺冠赛季数)字段值
    • 规则示例1:1950年首个赛季,除当年冠军Nino Farina外,其余所有车手的cum_seasons_won值为0
    • 规则示例2:截至数据集最新赛季,Juan Fangio的cum_seasons_won值应为5(对应其5次总冠军的历史成绩)
  • 数据集样例:
    F1数据集样例
  • 测试数据复现:可通过如下dput代码加载测试用样本数据
structure(list(full_name = c("Nino Farina", "Juan Fangio", "Alberto Ascari", 
"Alberto Ascari", "Juan Fangio", "Juan Fangio"), season_year = structure(c(-7305, 
-6940, -6575, -6209, -5844, -5479), class = "Date"), season_won = c(1, 
1, 1, 1, 1, 1), cum_seasons_won = c(1, 1, 1, 2, 2, 3)), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L), groups = structure(list(
    full_name = c("Alberto Ascari", "Juan Fangio", "Nino Farina"
    ), .rows = structure(list(3:4, c(2L, 5L, 6L), 1L), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -3L), .drop = TRUE))

注:因不清楚该类数据转换操作的标准术语,问题表述可能存在不严谨之处

实现代码

优先使用dplyr+tidyr的tidyverse语法实现,逻辑简洁易读:

library(dplyr)
library(tidyr)

# 假设原始清洗后的数据集命名为f1_raw,包含字段:
# full_name: 车手姓名
# season_year: 赛季年份(Date格式)
# season_won: 当赛季是否夺冠,1=夺冠,0=未夺冠

f1_processed <- f1_raw %>%
  # 生成所有赛季、所有车手的全量交叉组合,缺失的未夺冠记录自动补全
  complete(season_year, full_name, fill = list(season_won = 0)) %>%
  # 按车手分组,按赛季升序排序
  group_by(full_name) %>%
  arrange(season_year, .by_group = TRUE) %>%
  # 逐赛季累计夺冠次数
  mutate(cum_seasons_won = cumsum(season_won)) %>%
  ungroup()

逻辑说明

  • 核心是先补全所有「赛季-车手」组合,解决原始数据只有夺冠记录、缺失非夺冠条目导致累计值无法对齐所有行的问题
  • complete()函数会自动遍历所有出现过的赛季、所有出现过的车手生成全配对,未夺冠的赛季默认将season_won填充为0
  • 分组排序后用cumsum()做累计求和:未夺冠赛季累计值和上一赛季持平,夺冠赛季累计值+1,完全匹配需求
  • 测试样例验证:样本数据中Juan Fangio共出现3次夺冠记录,运行后其最后一条记录累计值为3,和样本逻辑一致;替换为全量数据后会正确计算到5次的累计值

替代方案(无tidyr依赖)

如果不想加载tidyr,也可以用base R生成全量组合后合并,逻辑完全一致:

# 生成所有赛季+车手的组合
all_combo <- expand.grid(
  season_year = unique(f1_raw$season_year),
  full_name = unique(f1_raw$full_name)
)
# 合并原始数据
f1_merged <- merge(all_combo, f1_raw, by = c("season_year", "full_name"), all.x = TRUE)
f1_merged[is.na(f1_merged$season_won), "season_won"] <- 0
# 排序计算累计值
f1_merged <- f1_merged[order(f1_merged$full_name, f1_merged$season_year), ]
f1_merged$cum_seasons_won <- ave(f1_merged$season_won, f1_merged$full_name, FUN = cumsum)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:18:23