##Read in and explore the data

baseball = read.csv("baseball.csv")
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 ...
# How many team/year pairs in the whole dataset?
nrow(baseball)                    # 1232
[1] 1232
# How many distinct years?
length(table(baseball$Year))      # 47
[1] 47

Limit to teams that made the playoffs

baseball = subset(baseball, Playoffs == 1)
nrow(baseball)                    # 244
[1] 244
table(table(baseball$Year))

 2  4  8 10 
 7 23 16  1 

Add the NumCompetitors predictor

PlayoffTable = table(baseball$Year)
PlayoffTable[c("1990", "2001")]

1990 2001 
   4    8 
baseball$NumCompetitors = PlayoffTable[as.character(baseball$Year)]
table(baseball$NumCompetitors)    # 8-team years -> 128

  2   4   8  10 
 14  92 128  10 

Define the WorldSeries outcome

baseball$WorldSeries = as.numeric(baseball$RankPlayoffs == 1)
table(baseball$WorldSeries)       # 197 did NOT win, 47 won

  0   1 
197  47 

Twelve bivariate logistic regression models

model1  <- glm(WorldSeries ~ Year,           data=baseball, family="binomial")
model2  <- glm(WorldSeries ~ RS,             data=baseball, family="binomial")
model3  <- glm(WorldSeries ~ RA,             data=baseball, family="binomial")
model4  <- glm(WorldSeries ~ W,              data=baseball, family="binomial")
model5  <- glm(WorldSeries ~ OBP,            data=baseball, family="binomial")
model6  <- glm(WorldSeries ~ SLG,            data=baseball, family="binomial")
model7  <- glm(WorldSeries ~ BA,             data=baseball, family="binomial")
model8  <- glm(WorldSeries ~ RankSeason,     data=baseball, family="binomial")
model9  <- glm(WorldSeries ~ OOBP,           data=baseball, family="binomial")
model10 <- glm(WorldSeries ~ OSLG,           data=baseball, family="binomial")
model11 <- glm(WorldSeries ~ NumCompetitors, data=baseball, family="binomial")
model12 <- glm(WorldSeries ~ League,         data=baseball, family="binomial")
summary(model1)   # Year            -> significant

Call:
glm(formula = WorldSeries ~ Year, family = "binomial", data = baseball)

Coefficients:
            Estimate Std. Error z value Pr(>|z|)   
(Intercept) 72.23602   22.64409    3.19  0.00142 **
Year        -0.03700    0.01138   -3.25  0.00115 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 239.12  on 243  degrees of freedom
Residual deviance: 228.35  on 242  degrees of freedom
AIC: 232.35

Number of Fisher Scoring iterations: 4
summary(model3)   # RA              -> significant

Call:
glm(formula = WorldSeries ~ RA, family = "binomial", data = baseball)

Coefficients:
             Estimate Std. Error z value Pr(>|z|)  
(Intercept)  1.888174   1.483831   1.272   0.2032  
RA          -0.005053   0.002273  -2.223   0.0262 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 239.12  on 243  degrees of freedom
Residual deviance: 233.88  on 242  degrees of freedom
AIC: 237.88

Number of Fisher Scoring iterations: 4
summary(model8)   # RankSeason      -> significant

Call:
glm(formula = WorldSeries ~ RankSeason, family = "binomial", 
    data = baseball)

Coefficients:
            Estimate Std. Error z value Pr(>|z|)  
(Intercept)  -0.8256     0.3268  -2.527   0.0115 *
RankSeason   -0.2069     0.1027  -2.016   0.0438 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 239.12  on 243  degrees of freedom
Residual deviance: 234.75  on 242  degrees of freedom
AIC: 238.75

Number of Fisher Scoring iterations: 4
summary(model11)  # NumCompetitors  -> significant (strongest)

Call:
glm(formula = WorldSeries ~ NumCompetitors, family = "binomial", 
    data = baseball)

Coefficients:
               Estimate Std. Error z value Pr(>|z|)    
(Intercept)     0.03868    0.43750   0.088 0.929559    
NumCompetitors -0.25220    0.07422  -3.398 0.000678 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 239.12  on 243  degrees of freedom
Residual deviance: 226.96  on 242  degrees of freedom
AIC: 230.96

Number of Fisher Scoring iterations: 4
# The remaining eight (RS, W, OBP, SLG, BA, OOBP, OSLG, League) are NOT significant.

Significant bivariate predictors: Year, RA, RankSeason, NumCompetitors.

Multivariate model

LogModel = glm(WorldSeries ~ Year + RA + RankSeason + NumCompetitors,
               data=baseball, family=binomial)
summary(LogModel)   # None of the four is significant -> multicollinearity

Call:
glm(formula = WorldSeries ~ Year + RA + RankSeason + NumCompetitors, 
    family = binomial, data = baseball)

Coefficients:
                 Estimate Std. Error z value Pr(>|z|)
(Intercept)    12.5874376 53.6474210   0.235    0.814
Year           -0.0061425  0.0274665  -0.224    0.823
RA             -0.0008238  0.0027391  -0.301    0.764
RankSeason     -0.0685046  0.1203459  -0.569    0.569
NumCompetitors -0.1794264  0.1815933  -0.988    0.323

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 239.12  on 243  degrees of freedom
Residual deviance: 226.37  on 239  degrees of freedom
AIC: 236.37

Number of Fisher Scoring iterations: 4

Correlations among the four predictors

cor(baseball[c("Year", "RA", "RankSeason", "NumCompetitors")])
                    Year        RA RankSeason NumCompetitors
Year           1.0000000 0.4762422  0.3852191      0.9139548
RA             0.4762422 1.0000000  0.3991413      0.5136769
RankSeason     0.3852191 0.3991413  1.0000000      0.4247393
NumCompetitors 0.9139548 0.5136769  0.4247393      1.0000000
# Only Year / NumCompetitors are strongly correlated (0.914)

Two-variable models and AIC

model13 = glm(WorldSeries ~ Year + RA,                   data=baseball, family=binomial)
model14 = glm(WorldSeries ~ Year + RankSeason,           data=baseball, family=binomial)
model15 = glm(WorldSeries ~ Year + NumCompetitors,       data=baseball, family=binomial)
model16 = glm(WorldSeries ~ RA + RankSeason,             data=baseball, family=binomial)
model17 = glm(WorldSeries ~ RA + NumCompetitors,         data=baseball, family=binomial)
model18 = glm(WorldSeries ~ RankSeason + NumCompetitors, data=baseball, family=binomial)
# Compare AIC across all 10 models; lowest wins
AIC(model1, model3, model8, model11,
    model13, model14, model15, model16, model17, model18)

The lowest AIC belongs to model11 (NumCompetitors alone), AIC = 230.96.

Conclusion

None of the two-variable models had both variables significant, so none beats a simple bivariate model. The best model overall uses only NumCompetitors — the number of playoff teams — which has nothing to do with team quality. Once a team makes the playoffs, regular-season performance does not predict the World Series winner, supporting Billy Beane’s claim in Moneyball that winning the playoffs comes down to luck.

LS0tCnRpdGxlOiAiSW4tQ2xhc3MgQWN0aXZpdHkgIzE1IOKAlCBQcmVkaWN0aW5nIHRoZSBXb3JsZCBTZXJpZXMgV2lubmVyIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojI1JlYWQgaW4gYW5kIGV4cGxvcmUgdGhlIGRhdGEKCmBgYHtyIHJlYWR9CmJhc2ViYWxsID0gcmVhZC5jc3YoImJhc2ViYWxsLmNzdiIpCnN0cihiYXNlYmFsbCkKCiMgSG93IG1hbnkgdGVhbS95ZWFyIHBhaXJzIGluIHRoZSB3aG9sZSBkYXRhc2V0Pwpucm93KGJhc2ViYWxsKSAgICAgICAgICAgICAgICAgICAgIyAxMjMyCgojIEhvdyBtYW55IGRpc3RpbmN0IHllYXJzPwpsZW5ndGgodGFibGUoYmFzZWJhbGwkWWVhcikpICAgICAgIyA0NwpgYGAKCiMjIExpbWl0IHRvIHRlYW1zIHRoYXQgbWFkZSB0aGUgcGxheW9mZnMKCmBgYHtyIHN1YnNldH0KYmFzZWJhbGwgPSBzdWJzZXQoYmFzZWJhbGwsIFBsYXlvZmZzID09IDEpCm5yb3coYmFzZWJhbGwpICAgICAgICAgICAgICAgICAgICAjIDI0NAp0YWJsZSh0YWJsZShiYXNlYmFsbCRZZWFyKSkKYGBgCgojIyBBZGQgdGhlIE51bUNvbXBldGl0b3JzIHByZWRpY3RvcgoKYGBge3IgbnVtY29tcH0KUGxheW9mZlRhYmxlID0gdGFibGUoYmFzZWJhbGwkWWVhcikKUGxheW9mZlRhYmxlW2MoIjE5OTAiLCAiMjAwMSIpXQpiYXNlYmFsbCROdW1Db21wZXRpdG9ycyA9IFBsYXlvZmZUYWJsZVthcy5jaGFyYWN0ZXIoYmFzZWJhbGwkWWVhcildCnRhYmxlKGJhc2ViYWxsJE51bUNvbXBldGl0b3JzKSAgICAjIDgtdGVhbSB5ZWFycyAtPiAxMjgKYGBgCgojIyBEZWZpbmUgdGhlIFdvcmxkU2VyaWVzIG91dGNvbWUKCmBgYHtyIHdzfQpiYXNlYmFsbCRXb3JsZFNlcmllcyA9IGFzLm51bWVyaWMoYmFzZWJhbGwkUmFua1BsYXlvZmZzID09IDEpCnRhYmxlKGJhc2ViYWxsJFdvcmxkU2VyaWVzKSAgICAgICAjIDE5NyBkaWQgTk9UIHdpbiwgNDcgd29uCmBgYAoKIyMgVHdlbHZlIGJpdmFyaWF0ZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVscwoKYGBge3IgYml2YXJpYXRlLCByZXN1bHRzPSdoaWRlJ30KbW9kZWwxICA8LSBnbG0oV29ybGRTZXJpZXMgfiBZZWFyLCAgICAgICAgICAgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PSJiaW5vbWlhbCIpCm1vZGVsMiAgPC0gZ2xtKFdvcmxkU2VyaWVzIH4gUlMsICAgICAgICAgICAgIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQptb2RlbDMgIDwtIGdsbShXb3JsZFNlcmllcyB+IFJBLCAgICAgICAgICAgICBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9ImJpbm9taWFsIikKbW9kZWw0ICA8LSBnbG0oV29ybGRTZXJpZXMgfiBXLCAgICAgICAgICAgICAgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PSJiaW5vbWlhbCIpCm1vZGVsNSAgPC0gZ2xtKFdvcmxkU2VyaWVzIH4gT0JQLCAgICAgICAgICAgIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQptb2RlbDYgIDwtIGdsbShXb3JsZFNlcmllcyB+IFNMRywgICAgICAgICAgICBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9ImJpbm9taWFsIikKbW9kZWw3ICA8LSBnbG0oV29ybGRTZXJpZXMgfiBCQSwgICAgICAgICAgICAgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PSJiaW5vbWlhbCIpCm1vZGVsOCAgPC0gZ2xtKFdvcmxkU2VyaWVzIH4gUmFua1NlYXNvbiwgICAgIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQptb2RlbDkgIDwtIGdsbShXb3JsZFNlcmllcyB+IE9PQlAsICAgICAgICAgICBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9ImJpbm9taWFsIikKbW9kZWwxMCA8LSBnbG0oV29ybGRTZXJpZXMgfiBPU0xHLCAgICAgICAgICAgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PSJiaW5vbWlhbCIpCm1vZGVsMTEgPC0gZ2xtKFdvcmxkU2VyaWVzIH4gTnVtQ29tcGV0aXRvcnMsIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQptb2RlbDEyIDwtIGdsbShXb3JsZFNlcmllcyB+IExlYWd1ZSwgICAgICAgICBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9ImJpbm9taWFsIikKYGBgCgpgYGB7ciBiaXZhcmlhdGUtc3VtbWFyaWVzfQpzdW1tYXJ5KG1vZGVsMSkgICAjIFllYXIgICAgICAgICAgICAtPiBzaWduaWZpY2FudApzdW1tYXJ5KG1vZGVsMykgICAjIFJBICAgICAgICAgICAgICAtPiBzaWduaWZpY2FudApzdW1tYXJ5KG1vZGVsOCkgICAjIFJhbmtTZWFzb24gICAgICAtPiBzaWduaWZpY2FudApzdW1tYXJ5KG1vZGVsMTEpICAjIE51bUNvbXBldGl0b3JzICAtPiBzaWduaWZpY2FudCAoc3Ryb25nZXN0KQojIFRoZSByZW1haW5pbmcgZWlnaHQgKFJTLCBXLCBPQlAsIFNMRywgQkEsIE9PQlAsIE9TTEcsIExlYWd1ZSkgYXJlIE5PVCBzaWduaWZpY2FudC4KYGBgCgoqKlNpZ25pZmljYW50IGJpdmFyaWF0ZSBwcmVkaWN0b3JzOiBZZWFyLCBSQSwgUmFua1NlYXNvbiwgTnVtQ29tcGV0aXRvcnMuKioKCiMjIE11bHRpdmFyaWF0ZSBtb2RlbAoKYGBge3IgbXVsdGl9CkxvZ01vZGVsID0gZ2xtKFdvcmxkU2VyaWVzIH4gWWVhciArIFJBICsgUmFua1NlYXNvbiArIE51bUNvbXBldGl0b3JzLAogICAgICAgICAgICAgICBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9Ymlub21pYWwpCnN1bW1hcnkoTG9nTW9kZWwpICAgIyBOb25lIG9mIHRoZSBmb3VyIGlzIHNpZ25pZmljYW50IC0+IG11bHRpY29sbGluZWFyaXR5CmBgYAoKIyMgQ29ycmVsYXRpb25zIGFtb25nIHRoZSBmb3VyIHByZWRpY3RvcnMKCmBgYHtyIGNvcn0KY29yKGJhc2ViYWxsW2MoIlllYXIiLCAiUkEiLCAiUmFua1NlYXNvbiIsICJOdW1Db21wZXRpdG9ycyIpXSkKIyBPbmx5IFllYXIgLyBOdW1Db21wZXRpdG9ycyBhcmUgc3Ryb25nbHkgY29ycmVsYXRlZCAoMC45MTQpCmBgYAoKIyMgVHdvLXZhcmlhYmxlIG1vZGVscyBhbmQgQUlDCgpgYGB7ciB0d292YXIsIHJlc3VsdHM9J2hpZGUnfQptb2RlbDEzID0gZ2xtKFdvcmxkU2VyaWVzIH4gWWVhciArIFJBLCAgICAgICAgICAgICAgICAgICBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9Ymlub21pYWwpCm1vZGVsMTQgPSBnbG0oV29ybGRTZXJpZXMgfiBZZWFyICsgUmFua1NlYXNvbiwgICAgICAgICAgIGRhdGE9YmFzZWJhbGwsIGZhbWlseT1iaW5vbWlhbCkKbW9kZWwxNSA9IGdsbShXb3JsZFNlcmllcyB+IFllYXIgKyBOdW1Db21wZXRpdG9ycywgICAgICAgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PWJpbm9taWFsKQptb2RlbDE2ID0gZ2xtKFdvcmxkU2VyaWVzIH4gUkEgKyBSYW5rU2Vhc29uLCAgICAgICAgICAgICBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9Ymlub21pYWwpCm1vZGVsMTcgPSBnbG0oV29ybGRTZXJpZXMgfiBSQSArIE51bUNvbXBldGl0b3JzLCAgICAgICAgIGRhdGE9YmFzZWJhbGwsIGZhbWlseT1iaW5vbWlhbCkKbW9kZWwxOCA9IGdsbShXb3JsZFNlcmllcyB+IFJhbmtTZWFzb24gKyBOdW1Db21wZXRpdG9ycywgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PWJpbm9taWFsKQpgYGAKCmBgYHtyIGFpY30KIyBDb21wYXJlIEFJQyBhY3Jvc3MgYWxsIDEwIG1vZGVsczsgbG93ZXN0IHdpbnMKQUlDKG1vZGVsMSwgbW9kZWwzLCBtb2RlbDgsIG1vZGVsMTEsCiAgICBtb2RlbDEzLCBtb2RlbDE0LCBtb2RlbDE1LCBtb2RlbDE2LCBtb2RlbDE3LCBtb2RlbDE4KQpgYGAKClRoZSBsb3dlc3QgQUlDIGJlbG9uZ3MgdG8gKiptb2RlbDExIChOdW1Db21wZXRpdG9ycyBhbG9uZSksIEFJQyA9IDIzMC45NioqLgoKIyMgQ29uY2x1c2lvbgoKTm9uZSBvZiB0aGUgdHdvLXZhcmlhYmxlIG1vZGVscyBoYWQgYm90aCB2YXJpYWJsZXMgc2lnbmlmaWNhbnQsIHNvIG5vbmUgYmVhdHMgYQpzaW1wbGUgYml2YXJpYXRlIG1vZGVsLiBUaGUgYmVzdCBtb2RlbCBvdmVyYWxsIHVzZXMgb25seSBgTnVtQ29tcGV0aXRvcnNgIOKAlCB0aGUKbnVtYmVyIG9mIHBsYXlvZmYgdGVhbXMg4oCUIHdoaWNoIGhhcyBub3RoaW5nIHRvIGRvIHdpdGggdGVhbSBxdWFsaXR5LiBPbmNlIGEgdGVhbQptYWtlcyB0aGUgcGxheW9mZnMsIHJlZ3VsYXItc2Vhc29uIHBlcmZvcm1hbmNlIGRvZXMgbm90IHByZWRpY3QgdGhlIFdvcmxkIFNlcmllcwp3aW5uZXIsIHN1cHBvcnRpbmcgQmlsbHkgQmVhbmUncyBjbGFpbSBpbiBNb25leWJhbGwgdGhhdCB3aW5uaW5nIHRoZSBwbGF5b2Zmcwpjb21lcyBkb3duIHRvIGx1Y2suCg==