Question:
Using R, build a regression model for data that interests you. Conduct residual analysis. Was the linear model appropriate? Why or why not?
Answer:
For my example, I am going to use some advanced hockey statistics available at https://www.hockey-reference.com/analytics/. I intend to use the same data for both Week 11 and 12 discussion topics.
First, let me provide a little detail on what i’m trying to do. A common indicator of good play in the NHL is called corsi for percentage. Simply put, corsi for percentage is the ratio of good events to the total number of events that occur. Now, there is a statistic called relative corsi for percentage which is the difference between the corsi for percentage of the team when the player is on the ice compared to when he is off. To summarize, this statistic is a measure of the difference of good things happening when a player is on the ice compared to when he is off. However, there are many factors that put players in a good position (which I explain below) to generate good things. Therefore, it is unclear if a player with a good relative corsi for percentage is a result of their skill or just their deployment (how they are used).
Is it possible to create a linear regression that can provide us a predicted corsi for percentage based on how the player is deployed? If so, will it help us evaluate if someone is over or underperformaning compared to their usage?
I will quickly explain just one of the advanced statistics available to us in this data set, offensive zone start percentage. This will be the predictor in our one-variable analysis this week; the others will be incorporated next week and their explanation can be found by some easy googling. When there is a stoppage in play, a faceoff occurs. Between stoppages, teams can switch the players that are on the bench for ones on the ice. If a player comes on to the ice for a faceoff that occurs in the oppoents end, this is an offensive zone start. The ratio we are analyzing is simply the percentage of total times a player comes on to the ice in the offensive zone between plays. Below is an image that hopefully provides some clarification. Note this team is moving left to right.
Let’s take a look at how the predictor and response relate:
Here we can see that there does appear to be some correlation so let’s run a regression after splitting up the data between training and testing sets.
hockey_sv_lm <- lm(data = train_df, formula = CF. ~ oZS.)
summary(hockey_sv_lm)
##
## Call:
## lm(formula = CF. ~ oZS., data = train_df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -17.0006 -1.9232 0.2779 2.1375 8.9707
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 38.60708 0.77409 49.87 <2e-16 ***
## oZS. 0.22149 0.01541 14.37 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.136 on 611 degrees of freedom
## Multiple R-squared: 0.2526, Adjusted R-squared: 0.2514
## F-statistic: 206.6 on 1 and 611 DF, p-value: < 2.2e-16
The results show that offensive zone start percentage is a statistically significant predictor variable since the p value is below 0.05. We see that there is an \({R}^{2}\) value of 0.25 which is not great, but pretty good for such an advanced topic. The F-statistic does not have any meaning to us since we only have on variable. Now, let’s check the resitual plot:
While the median of the linear regression was not exactly zero, and the min/max magnitudes were not similar, the data appears to be approximately normally distributed, which indicates this may be a good variable to use in order to predict corsi for percentage. Now, let’s run this regression on the test data to see if it is actually a good fit.
predicted_vals <- predict(hockey_sv_lm, test_df)
delta <- predicted_vals - test_df$CF.
(tt <- t.test(delta, conf.level = 0.95))
##
## One Sample t-test
##
## data: delta
## t = -0.94873, df = 68, p-value = 0.3461
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -1.0493881 0.3730869
## sample estimates:
## mean of x
## -0.3381506
The confidence interval ecompasses zero and has a range of [-1.0493881 - 0.3730869], which is fairly tight considering corsi for percentage ranges from [10 - 80]
Next week, I will add in the additional variables from this data source to attempt a fully predictive model.
Question:
Using R, build a multiple regression model for data that interests you. Include in this model at least one quadratic term, one dichotomous term, and one dichotomous vs. quantitative interaction term. Interpret all coefficients. Conduct residual analysis. Was the linear model appropriate? Why or why not?
Answer:
For the multi-regression example, let’s look at a comparison of all the variables:
library(GGally)
##
## Attaching package: 'GGally'
## The following object is masked from 'package:dplyr':
##
## nasa
drops <- c("Tm")
ggpairs(player_df[, !(names(player_df) %in% drops)], lower = list(combo = wrap("facethist", bins = 10)))
Now, using the deployment and positional statistics in this data, we can create a first attempt at a linear regression. Our dichotomous variable is the player’s position, our dichomotomous/continous interation term is position vs. average time on ice per game, and we have included one quadratic term for each variable.
hockey_lm <- lm(data = train_df, formula = CF. ~ Pos * TOI.EV. + Tm + I(TOI.EV.^2) + Age + I(Age^2) + oiSH. + I(oiSH.^2)+ oiSV. + I(oiSV.^2) + PDO + I(PDO^2) + oZS. + I(oZS.^2) + dZS. + I(dZS.^2) + TOI.60 + I(TOI.60^2) + Thru. + I(Thru.^2))
summary(hockey_lm)
##
## Call:
## lm(formula = CF. ~ Pos * TOI.EV. + Tm + I(TOI.EV.^2) + Age +
## I(Age^2) + oiSH. + I(oiSH.^2) + oiSV. + I(oiSV.^2) + PDO +
## I(PDO^2) + oZS. + I(oZS.^2) + dZS. + I(dZS.^2) + TOI.60 +
## I(TOI.60^2) + Thru. + I(Thru.^2), data = train_df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.7209 -1.4989 0.0186 1.4400 6.4341
##
## Coefficients: (1 not defined because of singularities)
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -5.441e+02 2.466e+03 -0.221 0.825436
## PosF 7.058e-02 2.606e+00 0.027 0.978404
## TOI.EV. 1.539e+00 9.910e-01 1.553 0.120943
## TmARI -1.457e-01 8.765e-01 -0.166 0.868017
## TmBOS 3.816e+00 8.827e-01 4.323 1.82e-05 ***
## TmBUF -1.561e+00 8.543e-01 -1.827 0.068178 .
## TmCAR 4.037e+00 8.821e-01 4.577 5.82e-06 ***
## TmCBJ 1.838e+00 8.120e-01 2.263 0.024008 *
## TmCGY 4.083e+00 8.395e-01 4.864 1.50e-06 ***
## TmCHI 3.232e+00 8.347e-01 3.872 0.000121 ***
## TmCOL -3.316e-01 8.252e-01 -0.402 0.687986
## TmDAL 3.615e+00 8.222e-01 4.396 1.32e-05 ***
## TmDET -2.067e-01 8.285e-01 -0.250 0.803058
## TmEDM 1.751e+00 8.626e-01 2.030 0.042796 *
## TmFLA 1.328e+00 8.304e-01 1.599 0.110394
## TmLAK 1.185e+00 8.272e-01 1.433 0.152450
## TmMIN -4.796e-01 8.494e-01 -0.565 0.572572
## TmMTL 9.003e-01 8.227e-01 1.094 0.274258
## TmNJD 3.954e-01 8.460e-01 0.467 0.640393
## TmNSH 2.658e+00 8.498e-01 3.128 0.001853 **
## TmNYI -8.151e-01 8.283e-01 -0.984 0.325499
## TmNYR -2.692e+00 8.379e-01 -3.212 0.001392 **
## TmOTT -1.445e+00 8.710e-01 -1.659 0.097639 .
## TmPHI 1.424e+00 8.231e-01 1.730 0.084171 .
## TmPIT 2.421e+00 8.740e-01 2.770 0.005793 **
## TmSJS 2.001e+00 8.278e-01 2.418 0.015927 *
## TmSTL 3.102e+00 8.403e-01 3.692 0.000244 ***
## TmTBL 3.311e+00 8.429e-01 3.928 9.63e-05 ***
## TmTOR 3.014e+00 8.266e-01 3.646 0.000291 ***
## TmTOT 4.988e-01 6.861e-01 0.727 0.467545
## TmVAN -3.740e-01 8.339e-01 -0.448 0.653981
## TmVEG 2.790e+00 8.308e-01 3.358 0.000838 ***
## TmWPG 3.674e+00 8.071e-01 4.553 6.50e-06 ***
## TmWSH -5.835e-01 8.247e-01 -0.708 0.479515
## I(TOI.EV.^2) -4.860e-02 3.261e-02 -1.491 0.136630
## Age 1.336e-01 2.407e-01 0.555 0.579121
## I(Age^2) -3.755e-03 4.233e-03 -0.887 0.375313
## oiSH. 1.109e+00 2.121e+00 0.523 0.601359
## I(oiSH.^2) -2.650e-02 3.133e-02 -0.846 0.398079
## oiSV. -1.708e+00 6.546e+00 -0.261 0.794296
## I(oiSV.^2) 1.241e-02 3.399e-02 0.365 0.715108
## PDO -3.316e+00 4.232e+00 -0.783 0.433716
## I(PDO^2) 1.220e-02 1.840e-02 0.663 0.507482
## oZS. 8.321e+00 2.465e+01 0.338 0.735823
## I(oZS.^2) -2.731e-04 9.627e-04 -0.284 0.776764
## dZS. 8.148e+00 2.465e+01 0.331 0.741120
## I(dZS.^2) NA NA NA NA
## TOI.60 -3.245e-01 4.975e-01 -0.652 0.514557
## I(TOI.60^2) 1.334e-02 1.402e-02 0.952 0.341587
## Thru. 4.873e-01 1.572e-01 3.101 0.002026 **
## I(Thru.^2) -4.644e-03 1.428e-03 -3.252 0.001214 **
## PosF:TOI.EV. 9.473e-02 1.812e-01 0.523 0.601273
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.37 on 562 degrees of freedom
## Multiple R-squared: 0.6075, Adjusted R-squared: 0.5726
## F-statistic: 17.4 on 50 and 562 DF, p-value: < 2.2e-16
So, we can start eliminating variables by removing the one with the highest p-value:
hockey_sv_tmp_lm <- update(hockey_lm, .~. - I(TOI.60^2))
summary(hockey_sv_tmp_lm)
##
## Call:
## lm(formula = CF. ~ Pos + TOI.EV. + Tm + I(TOI.EV.^2) + Age +
## I(Age^2) + oiSH. + I(oiSH.^2) + oiSV. + I(oiSV.^2) + PDO +
## I(PDO^2) + oZS. + I(oZS.^2) + dZS. + I(dZS.^2) + TOI.60 +
## Thru. + I(Thru.^2) + Pos:TOI.EV., data = train_df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.6491 -1.4703 -0.0083 1.4808 6.4315
##
## Coefficients: (1 not defined because of singularities)
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -4.944e+02 2.465e+03 -0.201 0.841131
## PosF -3.701e-01 2.565e+00 -0.144 0.885313
## TOI.EV. 7.845e-01 5.945e-01 1.320 0.187475
## TmARI -1.263e-01 8.762e-01 -0.144 0.885438
## TmBOS 3.836e+00 8.823e-01 4.347 1.64e-05 ***
## TmBUF -1.522e+00 8.532e-01 -1.784 0.075018 .
## TmCAR 4.023e+00 8.819e-01 4.562 6.23e-06 ***
## TmCBJ 1.820e+00 8.117e-01 2.243 0.025311 *
## TmCGY 4.075e+00 8.394e-01 4.855 1.56e-06 ***
## TmCHI 3.225e+00 8.346e-01 3.864 0.000125 ***
## TmCOL -3.578e-01 8.247e-01 -0.434 0.664585
## TmDAL 3.636e+00 8.218e-01 4.424 1.16e-05 ***
## TmDET -2.621e-01 8.264e-01 -0.317 0.751278
## TmEDM 1.760e+00 8.625e-01 2.041 0.041734 *
## TmFLA 1.352e+00 8.300e-01 1.629 0.103954
## TmLAK 1.243e+00 8.249e-01 1.507 0.132294
## TmMIN -3.992e-01 8.451e-01 -0.472 0.636861
## TmMTL 9.376e-01 8.217e-01 1.141 0.254335
## TmNJD 3.848e-01 8.459e-01 0.455 0.649365
## TmNSH 2.717e+00 8.474e-01 3.207 0.001420 **
## TmNYI -7.944e-01 8.279e-01 -0.959 0.337724
## TmNYR -2.688e+00 8.379e-01 -3.208 0.001411 **
## TmOTT -1.459e+00 8.708e-01 -1.675 0.094468 .
## TmPHI 1.431e+00 8.230e-01 1.739 0.082654 .
## TmPIT 2.381e+00 8.729e-01 2.728 0.006578 **
## TmSJS 2.017e+00 8.275e-01 2.437 0.015108 *
## TmSTL 3.121e+00 8.400e-01 3.715 0.000223 ***
## TmTBL 3.350e+00 8.419e-01 3.979 7.83e-05 ***
## TmTOR 2.992e+00 8.263e-01 3.621 0.000319 ***
## TmTOT 5.108e-01 6.860e-01 0.745 0.456840
## TmVAN -3.519e-01 8.335e-01 -0.422 0.673023
## TmVEG 2.781e+00 8.307e-01 3.348 0.000868 ***
## TmWPG 3.653e+00 8.067e-01 4.528 7.28e-06 ***
## TmWSH -5.647e-01 8.244e-01 -0.685 0.493644
## I(TOI.EV.^2) -2.295e-02 1.835e-02 -1.251 0.211589
## Age 1.276e-01 2.406e-01 0.531 0.595920
## I(Age^2) -3.674e-03 4.231e-03 -0.868 0.385579
## oiSH. 9.914e-01 2.118e+00 0.468 0.639861
## I(oiSH.^2) -2.634e-02 3.133e-02 -0.841 0.400875
## oiSV. -1.943e+00 6.541e+00 -0.297 0.766519
## I(oiSV.^2) 1.310e-02 3.398e-02 0.386 0.699950
## PDO -3.078e+00 4.225e+00 -0.728 0.466617
## I(PDO^2) 1.157e-02 1.838e-02 0.629 0.529419
## oZS. 7.837e+00 2.464e+01 0.318 0.750563
## I(oZS.^2) -3.720e-04 9.570e-04 -0.389 0.697605
## dZS. 7.654e+00 2.464e+01 0.311 0.756229
## I(dZS.^2) NA NA NA NA
## TOI.60 1.340e-01 1.244e-01 1.077 0.281865
## Thru. 4.990e-01 1.567e-01 3.185 0.001529 **
## I(Thru.^2) -4.743e-03 1.424e-03 -3.330 0.000924 ***
## PosF:TOI.EV. 1.254e-01 1.783e-01 0.703 0.482140
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.37 on 563 degrees of freedom
## Multiple R-squared: 0.6068, Adjusted R-squared: 0.5726
## F-statistic: 17.73 on 49 and 563 DF, p-value: < 2.2e-16
Looking at the Adjusted R-squared value, we are doing a little better. Fortunately, there is a step() function in R which performs backward elimation for us.
step_lm <- step(hockey_lm, trace = FALSE)
summary(step_lm)
##
## Call:
## lm(formula = CF. ~ Pos + TOI.EV. + Tm + I(TOI.EV.^2) + I(Age^2) +
## PDO + oZS. + I(TOI.60^2) + Thru. + I(Thru.^2), data = train_df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.5948 -1.5310 0.0128 1.5051 6.2558
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 41.7816573 6.7194227 6.218 9.72e-10 ***
## PosF 1.4477197 0.3913724 3.699 0.000237 ***
## TOI.EV. 1.4312354 0.2639737 5.422 8.71e-08 ***
## TmARI -0.1544976 0.8664233 -0.178 0.858538
## TmBOS 3.6849945 0.8560733 4.305 1.97e-05 ***
## TmBUF -1.6107662 0.8461391 -1.904 0.057455 .
## TmCAR 4.1078502 0.8701578 4.721 2.96e-06 ***
## TmCBJ 1.7790513 0.8012417 2.220 0.026785 *
## TmCGY 3.9566348 0.8306924 4.763 2.42e-06 ***
## TmCHI 3.1567736 0.8228466 3.836 0.000139 ***
## TmCOL -0.4045898 0.8129989 -0.498 0.618921
## TmDAL 3.6997047 0.8062180 4.589 5.48e-06 ***
## TmDET -0.2096180 0.8133202 -0.258 0.796707
## TmEDM 1.7791738 0.8520033 2.088 0.037219 *
## TmFLA 1.2634263 0.8170937 1.546 0.122599
## TmLAK 1.1889298 0.8162463 1.457 0.145780
## TmMIN -0.3961904 0.8324772 -0.476 0.634315
## TmMTL 0.8456135 0.8141849 1.039 0.299429
## TmNJD 0.3724745 0.8349040 0.446 0.655673
## TmNSH 2.6718016 0.8398836 3.181 0.001546 **
## TmNYI -0.7547338 0.7989889 -0.945 0.345256
## TmNYR -2.6690607 0.8282305 -3.223 0.001343 **
## TmOTT -1.3049977 0.8536993 -1.529 0.126907
## TmPHI 1.3658855 0.8111345 1.684 0.092743 .
## TmPIT 2.4878340 0.8576429 2.901 0.003865 **
## TmSJS 2.0942693 0.8116726 2.580 0.010123 *
## TmSTL 3.0789410 0.8256520 3.729 0.000211 ***
## TmTBL 3.3409741 0.8283688 4.033 6.25e-05 ***
## TmTOR 2.9882167 0.8156956 3.663 0.000272 ***
## TmTOT 0.4991768 0.6749556 0.740 0.459864
## TmVAN -0.5043615 0.8043731 -0.627 0.530893
## TmVEG 2.7619910 0.8173763 3.379 0.000777 ***
## TmWPG 3.6681411 0.7959405 4.609 5.00e-06 ***
## TmWSH -0.5345294 0.8035642 -0.665 0.506192
## I(TOI.EV.^2) -0.0455509 0.0118964 -3.829 0.000143 ***
## I(Age^2) -0.0014347 0.0004255 -3.372 0.000797 ***
## PDO -0.2547425 0.0507513 -5.019 6.93e-07 ***
## oZS. 0.1488610 0.0128588 11.577 < 2e-16 ***
## I(TOI.60^2) 0.0058335 0.0033343 1.750 0.080734 .
## Thru. 0.4844168 0.1533179 3.160 0.001664 **
## I(Thru.^2) -0.0046257 0.0013934 -3.320 0.000959 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.358 on 572 degrees of freedom
## Multiple R-squared: 0.6046, Adjusted R-squared: 0.5769
## F-statistic: 21.86 on 40 and 572 DF, p-value: < 2.2e-16
Okay, let’s check the residuals. Typically we would have to check that each variable consistent variability of residuals and is linearly related to the outcome. However, that is a more intensive task for the future. Right now, we can just check the base information.
Time to check our how good our model fits to the test data.
predicted_vals <- predict(step_lm, test_df)
delta <- predicted_vals - test_df$CF.
(tt <- t.test(delta, conf.level = 0.95))
##
## One Sample t-test
##
## data: delta
## t = 0.5372, df = 68, p-value = 0.5929
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -0.4010941 0.6966028
## sample estimates:
## mean of x
## 0.1477544
The confidence interval ecompasses zero and has a range of [-0.4010941 - 0.6966028], which is fairly tight considering corsi for percentage ranges from [10 - 80].
Well, we did all the work, let’s have some fun looking at the results. The chart below shows us the comparison of the predicted corsi for percentage against a player’s actual corsi for percentage. The higher their placement above the red line, the more the player has outperformed the prediction.
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
## Warning in RColorBrewer::brewer.pal(N, "Set2"): minimal value for n is 3, returning requested palette with 3 different levels
Finally, here are the top players based on the new difference:
Here is a table of the top players that have outperformed the prediction:
| Player | Tm | GP | Pos | oiSH. | oiSV. | oZS. | TOI.EV. | TK | E… | Thru. | CF. | predicted | CFDiff | CF..rel |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Eric Gryba | EDM | 21 | D | 9.1 | 89.7 | 57.5 | 13.166667 | 0.4285714 | 0.1 | 33.3 | 55.2 | 48.94419 | 6.255806 | 1.7 |
| Jordan Eberle | NYI | 80 | F | 9.9 | 89.7 | 52.2 | 14.016667 | 0.4625000 | 12.5 | 63.5 | 54.5 | 48.54395 | 5.956050 | 9.9 |
| Cody Franson | CHI | 23 | D | 4.5 | 93.1 | 65.8 | 14.383333 | 0.3043478 | 3.1 | 49.0 | 59.9 | 53.98265 | 5.917349 | 9.2 |
| Frank Vatrano | TOT | 39 | F | 6.7 | 92.8 | 58.9 | 10.033333 | 0.2564103 | 4.5 | 59.2 | 55.1 | 49.29924 | 5.800760 | 3.9 |
| Adam Lowry | WPG | 44 | F | 8.2 | 91.1 | 40.9 | 12.066667 | 0.4545455 | 8.3 | 67.0 | 56.2 | 50.46526 | 5.734735 | 4.3 |
| Brett Ritchie | DAL | 69 | F | 6.6 | 93.2 | 50.1 | 9.333333 | 0.1304348 | 8.9 | 56.1 | 56.5 | 50.85127 | 5.648731 | 5.9 |
| Richard Panik | TOT | 71 | F | 8.4 | 92.7 | 53.9 | 13.083333 | 0.3661972 | -0.4 | 50.6 | 55.2 | 49.98268 | 5.217316 | 5.5 |
| Ben Lovejoy | NJD | 56 | D | 6.7 | 92.5 | 41.1 | 13.450000 | 0.3928571 | 4.7 | 52.9 | 51.8 | 46.73472 | 5.065284 | 3.7 |
| Andrew Ladd | NYI | 72 | F | 9.3 | 92.7 | 45.2 | 12.916667 | 0.4027778 | -0.2 | 50.7 | 51.8 | 46.79112 | 5.008876 | 5.1 |
| Chris Kreider | NYR | 57 | F | 8.2 | 91.9 | 51.4 | 13.000000 | 0.2982456 | 5.3 | 58.3 | 51.5 | 46.59523 | 4.904772 | 7.3 |
| Gemel Smith | DAL | 44 | F | 7.7 | 95.1 | 48.2 | 9.233333 | 0.2727273 | 5.8 | 65.1 | 53.7 | 48.93488 | 4.765116 | 2.6 |
| Nino Niederreiter | MIN | 62 | F | 10.0 | 92.9 | 51.0 | 12.683333 | 0.3709677 | 4.4 | 60.7 | 52.6 | 47.84241 | 4.757587 | 6.6 |
| Nick Seeler | MIN | 21 | D | 9.8 | 95.1 | 48.3 | 13.583333 | 0.0952381 | 4.5 | 40.0 | 49.9 | 45.20667 | 4.693326 | 0.0 |
| Jussi Jokinen | TOT | 59 | F | 6.4 | 93.8 | 46.6 | 10.016667 | 0.3050847 | -0.3 | 52.6 | 51.2 | 46.71261 | 4.487387 | -0.1 |
| Craig Smith | NSH | 78 | F | 8.4 | 93.7 | 60.8 | 13.066667 | 0.7564103 | 14.8 | 61.5 | 56.8 | 52.41284 | 4.387161 | 8.3 |
| Paul Stastny | TOT | 81 | F | 8.9 | 90.4 | 53.6 | 14.716667 | 0.5308642 | 6.2 | 65.1 | 54.4 | 50.03264 | 4.367356 | 4.2 |
| Ondrej Kase | ANA | 64 | F | 9.0 | 94.4 | 54.2 | 12.566667 | 0.4531250 | 3.5 | 60.5 | 52.9 | 48.56933 | 4.330673 | 4.3 |
| Stefan Noesen | NJD | 71 | F | 8.8 | 93.1 | 37.5 | 12.733333 | 0.4647887 | 7.9 | 65.8 | 50.4 | 46.08934 | 4.310656 | 2.0 |
| Will Butcher | NJD | 80 | D | 8.2 | 91.0 | 62.0 | 13.200000 | 0.2500000 | 11.2 | 37.0 | 53.7 | 49.40011 | 4.299888 | 7.0 |
| Tim Heed | SJS | 29 | D | 7.6 | 90.0 | 63.0 | 12.966667 | 0.5172414 | 5.6 | 40.2 | 56.0 | 51.73987 | 4.260130 | 4.3 |