predict() FunctionThis activity uses the official baseball.csv file from
Canvas. The dataset contains team-level baseball statistics such as runs
scored, runs allowed, wins, on-base percentage, slugging percentage,
batting average, games played, and playoff results.
The goal is to practice importing a CSV file, exploring a data frame, creating new variables, producing basic visualizations, and building a simple linear regression model to predict wins.
Make sure baseball.csv is uploaded to the same
Posit/RStudio folder as this R Markdown file.
baseball <- read.csv("baseball.csv")
head(baseball)
## Team League Year RS RA W OBP SLG BA Playoffs RankSeason
## 1 ARI NL 2012 734 688 81 0.328 0.418 0.259 0 NA
## 2 ATL NL 2012 700 600 94 0.320 0.389 0.247 1 4
## 3 BAL AL 2012 712 705 93 0.311 0.417 0.247 1 5
## 4 BOS AL 2012 734 806 69 0.315 0.415 0.260 0 NA
## 5 CHC NL 2012 613 759 61 0.302 0.378 0.240 0 NA
## 6 CHW AL 2012 748 676 85 0.318 0.422 0.255 0 NA
## RankPlayoffs G OOBP OSLG
## 1 NA 162 0.317 0.415
## 2 5 162 0.306 0.378
## 3 4 162 0.315 0.403
## 4 NA 162 0.331 0.428
## 5 NA 162 0.335 0.424
## 6 NA 162 0.319 0.405
# View the structure of the dataset
str(baseball)
## 'data.frame': 1232 obs. of 15 variables:
## $ Team : chr "ARI" "ATL" "BAL" "BOS" ...
## $ League : chr "NL" "NL" "AL" "AL" ...
## $ Year : int 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 ...
## $ RS : int 734 700 712 734 613 748 669 667 758 726 ...
## $ RA : int 688 600 705 806 759 676 588 845 890 670 ...
## $ W : int 81 94 93 69 61 85 97 68 64 88 ...
## $ OBP : num 0.328 0.32 0.311 0.315 0.302 0.318 0.315 0.324 0.33 0.335 ...
## $ SLG : num 0.418 0.389 0.417 0.415 0.378 0.422 0.411 0.381 0.436 0.422 ...
## $ BA : num 0.259 0.247 0.247 0.26 0.24 0.255 0.251 0.251 0.274 0.268 ...
## $ Playoffs : int 0 1 1 0 0 0 1 0 0 1 ...
## $ RankSeason : int NA 4 5 NA NA NA 2 NA NA 6 ...
## $ RankPlayoffs: int NA 5 4 NA NA NA 4 NA NA 2 ...
## $ G : int 162 162 162 162 162 162 162 162 162 162 ...
## $ OOBP : num 0.317 0.306 0.315 0.331 0.335 0.319 0.305 0.336 0.357 0.314 ...
## $ OSLG : num 0.415 0.378 0.403 0.428 0.424 0.405 0.39 0.43 0.47 0.402 ...
# View the column names
names(baseball)
## [1] "Team" "League" "Year" "RS" "RA"
## [6] "W" "OBP" "SLG" "BA" "Playoffs"
## [11] "RankSeason" "RankPlayoffs" "G" "OOBP" "OSLG"
# View summary statistics
summary(baseball)
## Team League Year RS
## Length :1232 Length :1232 Min. :1962 Min. : 463.0
## N.unique : 39 N.unique : 2 1st Qu.:1977 1st Qu.: 652.0
## N.blank : 0 N.blank : 0 Median :1989 Median : 711.0
## Min.nchar: 3 Min.nchar: 2 Mean :1989 Mean : 715.1
## Max.nchar: 3 Max.nchar: 2 3rd Qu.:2002 3rd Qu.: 775.0
## Max. :2012 Max. :1009.0
##
## RA W OBP SLG
## Min. : 472.0 Min. : 40.0 Min. :0.2770 Min. :0.3010
## 1st Qu.: 649.8 1st Qu.: 73.0 1st Qu.:0.3170 1st Qu.:0.3750
## Median : 709.0 Median : 81.0 Median :0.3260 Median :0.3960
## Mean : 715.1 Mean : 80.9 Mean :0.3263 Mean :0.3973
## 3rd Qu.: 774.2 3rd Qu.: 89.0 3rd Qu.:0.3370 3rd Qu.:0.4210
## Max. :1103.0 Max. :116.0 Max. :0.3730 Max. :0.4910
##
## BA Playoffs RankSeason RankPlayoffs
## Min. :0.2140 Min. :0.0000 Min. :1.000 Min. :1.000
## 1st Qu.:0.2510 1st Qu.:0.0000 1st Qu.:2.000 1st Qu.:2.000
## Median :0.2600 Median :0.0000 Median :3.000 Median :3.000
## Mean :0.2593 Mean :0.1981 Mean :3.123 Mean :2.717
## 3rd Qu.:0.2680 3rd Qu.:0.0000 3rd Qu.:4.000 3rd Qu.:4.000
## Max. :0.2940 Max. :1.0000 Max. :8.000 Max. :5.000
## NAs :988 NAs :988
## G OOBP OSLG
## Min. :158.0 Min. :0.2940 Min. :0.3460
## 1st Qu.:162.0 1st Qu.:0.3210 1st Qu.:0.4010
## Median :162.0 Median :0.3310 Median :0.4190
## Mean :161.9 Mean :0.3323 Mean :0.4197
## 3rd Qu.:162.0 3rd Qu.:0.3430 3rd Qu.:0.4380
## Max. :165.0 Max. :0.3840 Max. :0.4990
## NAs :812 NAs :812
The dataset includes the following important variables:
Team: team abbreviationLeague: American League or National LeagueYear: season yearRS: runs scoredRA: runs allowedW: winsOBP: on-base percentageSLG: slugging percentageBA: batting averagePlayoffs: whether the team made the playoffsG: games playedOOBP: opponent on-base percentageOSLG: opponent slugging percentageRun differential is calculated as runs scored minus runs allowed.
\[ Run\ Differential = RS - RA \]
baseball$Run_Differential <- baseball$RS - baseball$RA
head(baseball[, c("Team", "Year", "RS", "RA", "Run_Differential", "W")])
## Team Year RS RA Run_Differential W
## 1 ARI 2012 734 688 46 81
## 2 ATL 2012 700 600 100 94
## 3 BAL 2012 712 705 7 93
## 4 BOS 2012 734 806 -72 69
## 5 CHC 2012 613 759 -146 61
## 6 CHW 2012 748 676 72 85
Winning percentage is calculated as wins divided by games played.
\[ Winning\ Percentage = \frac{W}{G} \]
baseball$Winning_Percentage <- baseball$W / baseball$G
head(baseball[, c("Team", "Year", "W", "G", "Winning_Percentage")])
## Team Year W G Winning_Percentage
## 1 ARI 2012 81 162 0.5000000
## 2 ATL 2012 94 162 0.5802469
## 3 BAL 2012 93 162 0.5740741
## 4 BOS 2012 69 162 0.4259259
## 5 CHC 2012 61 162 0.3765432
## 6 CHW 2012 85 162 0.5246914
summary(baseball[, c("RS", "RA", "Run_Differential", "W", "OBP", "SLG", "BA")])
## RS RA Run_Differential W
## Min. : 463.0 Min. : 472.0 Min. :-337 Min. : 40.0
## 1st Qu.: 652.0 1st Qu.: 649.8 1st Qu.: -72 1st Qu.: 73.0
## Median : 711.0 Median : 709.0 Median : 4 Median : 81.0
## Mean : 715.1 Mean : 715.1 Mean : 0 Mean : 80.9
## 3rd Qu.: 775.0 3rd Qu.: 774.2 3rd Qu.: 74 3rd Qu.: 89.0
## Max. :1009.0 Max. :1103.0 Max. : 309 Max. :116.0
## OBP SLG BA
## Min. :0.2770 Min. :0.3010 Min. :0.2140
## 1st Qu.:0.3170 1st Qu.:0.3750 1st Qu.:0.2510
## Median :0.3260 Median :0.3960 Median :0.2600
## Mean :0.3263 Mean :0.3973 Mean :0.2593
## 3rd Qu.:0.3370 3rd Qu.:0.4210 3rd Qu.:0.2680
## Max. :0.3730 Max. :0.4910 Max. :0.2940
plot(
baseball$RS,
baseball$W,
main = "Runs Scored vs. Wins",
xlab = "Runs Scored",
ylab = "Wins",
pch = 19
)
plot(
baseball$RA,
baseball$W,
main = "Runs Allowed vs. Wins",
xlab = "Runs Allowed",
ylab = "Wins",
pch = 19
)
plot(
baseball$Run_Differential,
baseball$W,
main = "Run Differential vs. Wins",
xlab = "Run Differential",
ylab = "Wins",
pch = 19
)
abline(lm(W ~ Run_Differential, data = baseball), lwd = 2)
The model predicts wins using run differential.
\[ Wins = Intercept + Slope \times Run\ Differential \]
wins_model <- lm(W ~ Run_Differential, data = baseball)
summary(wins_model)
##
## Call:
## lm(formula = W ~ Run_Differential, data = baseball)
##
## Residuals:
## Min 1Q Median 3Q Max
## -14.3767 -2.7765 0.0571 2.8022 12.8235
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 80.904221 0.113335 713.85 <2e-16 ***
## Run_Differential 0.104548 0.001103 94.78 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.978 on 1230 degrees of freedom
## Multiple R-squared: 0.8796, Adjusted R-squared: 0.8795
## F-statistic: 8983 on 1 and 1230 DF, p-value: < 2.2e-16
intercept <- coef(wins_model)[1]
slope <- coef(wins_model)[2]
intercept
## (Intercept)
## 80.90422
slope
## Run_Differential
## 0.1045482
The regression equation from this dataset is:
paste0(
"Predicted Wins = ",
round(intercept, 4),
" + ",
round(slope, 4),
" * Run Differential"
)
## [1] "Predicted Wins = 80.9042 + 0.1045 * Run Differential"
First calculate run differential:
\[ 763 - 614 = 149 \]
Then plug the value into the regression model.
runs_scored <- 763
runs_allowed <- 614
new_run_differential <- runs_scored - runs_allowed
new_run_differential
## [1] 149
predicted_wins <- intercept + slope * new_run_differential
predicted_wins
## (Intercept)
## 96.48191
round(predicted_wins, 1)
## (Intercept)
## 96.5
round(predicted_wins, 0)
## (Intercept)
## 96
A team that scores 763 runs and allows 614 runs is expected to win approximately 96.5 games, which rounds to about 96 wins.
predict() Functionnew_team <- data.frame(Run_Differential = 149)
predict(wins_model, newdata = new_team)
## 1
## 96.48191
aggregate(W ~ Playoffs, data = baseball, FUN = mean)
## Playoffs W
## 1 0 77.39372
## 2 1 95.11885
aggregate(Run_Differential ~ Playoffs, data = baseball, FUN = mean)
## Playoffs Run_Differential
## 1 0 -29.67004
## 2 1 120.13934
boxplot(
W ~ Playoffs,
data = baseball,
main = "Wins by Playoff Status",
xlab = "Playoff Status",
ylab = "Wins"
)
baseball_ordered <- baseball[order(-baseball$W), ]
head(baseball_ordered[, c("Team", "League", "Year", "RS", "RA", "Run_Differential", "W")], 10)
## Team League Year RS RA Run_Differential W
## 355 SEA AL 2001 927 627 300 116
## 440 NYY AL 1998 965 656 309 114
## 1070 BAL AL 1969 779 517 262 109
## 706 NYM NL 1986 783 578 205 108
## 955 CIN NL 1975 840 586 254 108
## 1046 BAL AL 1970 792 574 218 108
## 423 ATL NL 1998 826 581 245 106
## 267 STL NL 2004 855 659 196 105
## 507 ATL NL 1993 767 559 208 104
## 656 OAK AL 1988 800 620 180 104
This activity showed how to import and explore a baseball dataset in R, create run differential and winning percentage variables, visualize relationships between performance measures, build a linear regression model, and predict expected wins for a team based on runs scored and runs allowed.