Transformations and Multiple Regression

The files mlb_payrolls_train.csv and mlb_payrolls_test.csv contain observations for MLB teams and seasons with complete payroll and winning percentages for the current and previous seasons. The payroll source does not cover every team and season. The training file contains 1999–2018, and the testing file contains 2019 and 2021–2023. The shortened 2020 season is excluded as an outcome, but its winning percentages provide previous_wp for the 2021 rows.

The variables are:

  • team: team name
  • season: season of the outcome and payroll
  • winning_percentage: wins divided by games played
  • relative_payroll: team payroll divided by the MLB average in that season
  • previous_wp: the team’s winning percentage in the previous season

Relative payroll makes payroll comparable across seasons with different spending levels across MLB. Winning percentage from the previous season adds a measure of recent team performance that current payroll does not contain.

Fit all six candidate models with mlb_train. Load mlb_test only after all six models are fixed. Select the final model using testing RMSE, without refitting after viewing the scores.

Candidate Transformations

  1. Load mlb_payrolls_train.csv as mlb_train. Report the ranges of season and relative_payroll, then plot relative_payroll against winning_percentage.
mlb_train <- read_csv("data/mlb_payrolls_train.csv")
  1. Fit three models of winning_percentage using relative_payroll. Save them with the names below.

    • lin_payroll_model: relative_payroll
    • log_payroll_model: log(relative_payroll)
    • quad_payroll_model: relative_payroll and relative_payroll^2

    Use I() around the squared term.

lin_payroll_model <- lm(winning_percentage ~ relative_payroll, data = mlb_train)
log_payroll_model <- lm(winning_percentage ~ log(relative_payroll), data = mlb_train)
quad_payroll_model <- lm(winning_percentage ~ ..., data = mlb_train)
  1. Create payroll_grid, a tibble containing 150 evenly spaced relative_payroll values from the observed minimum to the observed maximum. Use each model to add a column of fitted winning percentages. Reshape the three columns of fitted values into a long table called payroll_grid_long.

  2. Plot the observed training data and add all three curves from payroll_grid_long. Map model to color so that each curve has a different color and the plot includes a legend.

Training Fit

  1. Add fitted values from the three models to mlb_train, using the same fitted value column names as in payroll_grid.

  2. Define rmse(), a function with predicted and actual arguments that returns RMSE. Use it to calculate the training RMSE for all three models and put the results in a long table called payroll_train_scores.

  3. Run the supplied code to add a column of random values, include it in the regression with linear payroll, and add the fitted values as lin_payroll_random. Use rmse() and reframe() to create random_training_scores, a long table comparing the training RMSE of lin_payroll and lin_payroll_random.

set.seed(2026)

mlb_train <- mlb_train %>%
  mutate(random_value = rnorm(n()))

lin_payroll_random_model <- lm(
  winning_percentage ~ relative_payroll + random_value,
  data = mlb_train
)

mlb_train <- mlb_train %>%
  mutate(lin_payroll_random = predict(lin_payroll_random_model))

random_value contains no baseball information. Its model still has slightly lower training RMSE because lm() has another coefficient to fit. A lower training RMSE alone does not identify the better model. The random predictor model is not a candidate for testing.

Adding Previous Season Winning Percentage

  1. Calculate the residuals from lin_payroll_model as observed winning percentage minus lin_payroll. Plot the residuals against previous_wp, add a horizontal line at zero, and add a fitted straight line with geom_smooth(). The fitted line should slope upward.

  2. Fit three multiple regression models by adding the untransformed previous_wp predictor to each payroll specification. Save them as lin_payroll_prev_wp_model, log_payroll_prev_wp_model, and quad_payroll_prev_wp_model. Add their fitted values to mlb_train as lin_payroll_prev_wp, log_payroll_prev_wp, and quad_payroll_prev_wp.

  3. Display the coefficients of log_payroll_prev_wp_model. Calculate the fitted difference in current winning percentage associated with a 0.100 increase in previous_wp, holding relative payroll constant.

  4. Calculate the training RMSE for the three multiple regression models. Combine these results with payroll_train_scores in a table called training_scores. Do not select a model or load the testing data.

Testing on Later Seasons

The later seasons measure whether relationships fitted through 2018 carry forward in time.

  1. Load mlb_payrolls_test.csv as mlb_test. Do not refit any model. Add predictions from all six fitted models.

  2. Calculate testing RMSE for all six models and combine those scores with training_scores. Make a bar chart with the training and testing bars next to each other for each model, and label every bar with its RMSE. Create best_payroll_model containing the model using only payroll with the lowest testing RMSE and best_overall_model containing the model with the lowest testing RMSE overall.