R语言if_else/ifelse函数异常:无法正确返回NFL获胜球队名称
Hey there! Let's work through why your attempts aren't behaving as expected and get that winning team column working correctly.
First, Let's Diagnose the Root Issue
Looking at your output, the tm_won1 and tm_won2 columns show numbers that look like score differences—but they're actually integer codes for factor levels. When you read in your data, R probably converted home_team and away_team to factor variables by default. Functions like ifelse() and case_when() handle factors by returning their underlying integer codes instead of the team names, which is why you're seeing those numbers instead of team labels.
Additionally, if_else() (from dplyr) is strict about type consistency—if the factor levels don't match perfectly between home_team and away_team, it'll return NA for cases where the false condition triggers (like the PHI vs WAS game in your data).
Let's Fix Each Attempt & Get a Working Solution
1. Fix the Factor Problem First
Before anything else, convert your team columns to character strings to avoid factor-related issues:
# Base R approach wk1$home_team <- as.character(wk1$home_team) wk1$away_team <- as.character(wk1$away_team) # Or dplyr approach (cleaner for multiple columns) wk1 <- wk1 %>% mutate(across(c(home_team, away_team), as.character))
2. Working if_else() Version
Now that teams are stored as characters, if_else() will work as intended (it enforces type consistency, which is good practice):
wk1$tm_won <- if_else(wk1$home_score < wk1$away_score, wk1$away_team, wk1$home_team)
This returns away_team when they score higher, home_team otherwise. For ties, it'll default to home_team—we'll adjust that next if needed.
3. Working ifelse() Version
Base R's ifelse() will now return character strings instead of factor codes:
wk1$tm_won1 <- ifelse(wk1$home_score < wk1$away_score, wk1$away_team, wk1$home_team)
4. Working dplyr + ifelse() with Tie Handling
Your third attempt failed due to factors. With character columns, this will work, and we'll explicitly handle ties:
wk1 <- wk1 %>% mutate(tm_won2 = ifelse(home_score < away_score, away_team, ifelse(home_score > away_score, home_team, NA)))
The NA will mark tie games (though NFL regular season ties are rare!).
5. Working case_when() Version
Your fourth attempt had a typo (a instead of NA for ties) and factor issues. Fix that with character columns:
wk1 <- wk1 %>% mutate(tm_won = case_when( home_score < away_score ~ away_team, home_score > away_score ~ home_team, TRUE ~ NA_character_ # Use NA_character_ to match character column type ))
Using NA_character_ ensures the return type matches the team name strings, avoiding type mismatches.
Example Output After Fixes
After running the above, your dataset should look like this:
| season | week | home_team | away_team | home_score | away_score | tm_won | tm_won1 | tm_won2 |
|---|---|---|---|---|---|---|---|---|
| 2019 | 1 | CHI | GB | 3 | 10 | GB | GB | GB |
| 2019 | 1 | CAR | LA | 27 | 30 | LA | LA | LA |
| 2019 | 1 | PHI | WAS | 32 | 27 | PHI | PHI | PHI |
| 2019 | 1 | NYJ | BUF | 16 | 17 | BUF | BUF | BUF |
| 2019 | 1 | MIN | ATL | 28 | 12 | MIN | MIN | MIN |
Quick Tip for Future Data Reads
To avoid factors altogether when reading data, use stringsAsFactors = FALSE in base R's read.csv(), or specify character columns with col_types in read_csv() (from the readr package).
内容的提问来源于stack exchange,提问作者new_r

