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

R语言:为数据框添加条件赋值列时mutate+case_when报错排查

问题描述

现有三个R语言数据框:

  • completed_games:存储已完成、且至少涉及1支FBS队的大学橄榄球比赛数据
  • VoA_Variables:存储各队统计数据、评分及排名
  • FCS:存储FCS大学橄榄球队评分

需求是筛选出涉及Air Force队的比赛数据生成AirForce数据框,并添加两列:

  1. home_VoA_rating:主队为FBS队时从VoA_Variables取对应VoA_Rating;为FCS队时从FCS取对应rating
  2. away_VoA_rating:客队按相同规则取值

当前执行mutate中的case_when时报错:

Error in mutate():
! Problem while computing home_VoA_rating = case_when(...).
Caused by error in case_when():
! TRUE ~ FCS$rating[FCS$team == home_team] must be length 10 or one, not 0.

将case_when替换为直接赋值0时代码可正常运行,需解决该条件赋值报错并实现目标列的正确添加。原代码如下:

AirForce <- completed_games |>
  filter(home_team == "Air Force" | away_team == "Air Force") |>
  mutate(home_VoA_rating = case_when(home_team %in% VoA_Variables$team ~ VoA_Variables$VoA_Rating[VoA_Variables$team == home_team],
                                     TRUE ~ FCS$rating[FCS$team == home_team]),
         away_VoA_rating = case_when(away_team %in% VoA_Variables$team ~ VoA_Variables$VoA_Rating[VoA_Variables$team == away_team],
                                     TRUE ~ FCS$rating[FCS$team == away_team]),
         actual_diff = case_when(home_team == 'Air Force' ~ home_points - away_points,
                                 TRUE ~ away_points - home_points),
         projected_diff = case_when(home_team == 'Air Force' ~ home_VoA_rating - away_VoA_rating,
                                    TRUE ~ away_VoA_rating - home_VoA_rating),
         Resume_Score = projected_diff - actual_diff)
报错原因

当某个球队既不在VoA_Variables也不在FCS中时,FCS$rating[FCS$team == home_team]会返回长度为0的向量,而case_when要求每个分支返回的向量长度必须与数据框行数一致(此处为10行)或长度为1,因此触发报错。

解决方案

推荐用左连接替代直接向量索引,这更符合dplyr的操作逻辑,也能避免索引匹配失败的问题,具体代码如下:

# 生成统一的球队评分表,合并FBS和FCS的评分数据
team_ratings <- bind_rows(
  VoA_Variables |> select(team, VoA_Rating) |> rename(rating = VoA_Rating),
  FCS |> select(team, rating)
)

# 筛选比赛数据并匹配评分
AirForce <- completed_games |>
  filter(home_team == "Air Force" | away_team == "Air Force") |>
  # 匹配主队评分
  left_join(team_ratings, by = c("home_team" = "team")) |>
  rename(home_VoA_rating = rating) |>
  # 匹配客队评分
  left_join(team_ratings, by = c("away_team" = "team")) |>
  rename(away_VoA_rating = rating) |>
  # 计算后续差值列
  mutate(
    actual_diff = if_else(home_team == 'Air Force', home_points - away_points, away_points - home_points),
    projected_diff = if_else(home_team == 'Air Force', home_VoA_rating - away_VoA_rating, away_VoA_rating - home_VoA_rating),
    Resume_Score = projected_diff - actual_diff
  )

方案说明

  1. 用bind_rows合并两个评分表,确保所有FBS和FCS球队的评分都在同一表中
  2. left_join会自动按球队名称匹配评分,找不到匹配时返回NA,彻底避免空向量问题
  3. 用if_else替代双分支的case_when,逻辑更简洁高效

备选方案(保留case_when写法)

如果必须使用case_when,可添加分支处理球队不在两个表中的情况,确保返回长度合法的向量:

AirForce <- completed_games |>
  filter(home_team == "Air Force" | away_team == "Air Force") |>
  mutate(
    home_VoA_rating = case_when(
      home_team %in% VoA_Variables$team ~ VoA_Variables$VoA_Rating[VoA_Variables$team == home_team],
      home_team %in% FCS$team ~ FCS$rating[FCS$team == home_team],
      TRUE ~ NA_real_  # 处理既不在FBS也不在FCS的球队
    ),
    away_VoA_rating = case_when(
      away_team %in% VoA_Variables$team ~ VoA_Variables$VoA_Rating[VoA_Variables$team == away_team],
      away_team %in% FCS$team ~ FCS$rating[FCS$team == away_team],
      TRUE ~ NA_real_
    ),
    actual_diff = case_when(home_team == 'Air Force' ~ home_points - away_points,
                           TRUE ~ away_points - home_points),
    projected_diff = case_when(home_team == 'Air Force' ~ home_VoA_rating - away_VoA_rating,
                              TRUE ~ away_VoA_rating - home_VoA_rating),
    Resume_Score = projected_diff - actual_diff
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:42:06