1. On 8/24/2021, the Cardinals trail the Tigers 4-3 going into the top of the 9th. To begin this inning, Daz Cameron doubled, Akil Baddoo struck out, and Jonathan Schoop grounded out, moving Cameron to 3rd. The batter is now Robbie Grossman. Assume Luis Garcia will pitch through the 5th spot in the batting order, Jeimer Candelario. Should the Cardinals intentionally walk Grossman? https://www.mlb.com/gameday/tigers-vs-cardinals/2021/08/24/632781/final/box

This hypothetical explores the tradeoffs of pitching to a good hitter or putting a runner on to face a weaker hitter. After doing some quick estimations, it was very clear that the right thing to do is intentionally walk Grossman and pitch to short. You are not giving up very much at all to get to face a much weaker hitter.

This got me thinking however. What if the score was reveresed, and the Cardinals were winning 4-3. The runner on third is the tying run and Grossman is much more likely to get a hit than Short but is it worth putting the winning run on first? This is a scenario that I thought was worthy of a deep dive into via simulation.

My plan is to randomly draw previous outcomes of at bats from the players current season stats and use those as the results. I understand that this is a subjective decision that doesn’t take the entire picture into consideration. Mainly, I am excluding the pitchers stats alltogether as well as the batter’s righty-lefty splits. Thats ok as all models must make simplifications at some point. I will simulate at the rest of the game 10,000 times after pitching to Grossman, or deciding to walk him. This method of similation is known as the monte carlo method.

#this function simulates a single at bat from grossman by drawing 
#randomly from 655 (his at bats + BB) in 2021
grossmanAB=function()
{
x=runif(1,1,655) 
if (x<=23)
{
  grossman="hr"
}else if (x<=26)
{
  grossman="3b"
}else if (x<=49)
{
  grossman="2b"
}else if (x<=133)
{
  grossman="1b"
}else if (x<=231)
{
  grossman="bb"
}else
{
  grossman="out"
}
return(grossman)
}
#simulates one of shorts at bats
shortAB=function(){
y=runif(1,1,178) 
if (y<=6)
{
  short="hr"
}else if (y<=10)
{
  short="2b"
}else if (y<=22)
{
  short="1b"
}else if (y<=44)
{
  short="bb"
}else
{
  short="out"
}
return(short)
}
#simulates a candelario at bat
candelarioAB=function(){
z=runif(1,1,178) 
if (z<=6)
{
  candy="hr"
}else if (z<=10)
{
  candy="2b"
}else if (z<=22)
{
  candy="1b"
}else if (z<=44)
{
  candy="bb"
}else
{
  candy="out"
}
return(candy)
}
#Simulating the game if the Cards go after Grossman
i=1
results=list()
while (i<100002)
{
             #grossman gets out
  g=grossmanAB()
  if(g=="out")
  {
    bottom9="none"
  }else if (g=="1b")   #if grossman singles
  {
    s=shortAB()
    if (s=="out")
    {
      bottom9="tied"
    }else if(s=="hr")
    {
      bottom9="2"
    }else if(s=="2b")
    {
      #I am going to truncate the problem and say that the runner scores half from first 1/3 of the time.
      temp=runif(1,0,3)  #the first temp sees if the runner will score form first on the double
      temp2=runif(1,0,5)  # the second temp dictates the number of runs scored afterwards
      if(temp<1 & temp2<1)  #runner scores + chart
      {
        bottom9="2"
      }else if(temp<1 & temp2>1)
      {
        bottom9="1"
      }else if(temp>1 & temp2<1) #runner stays at third + chart
      {
        bottom9="2"
      }else if(temp>1 & temp2>1)
      {
        bottom9="tied"
      }
    }else if(s=="1b"|s=="bb")
      {
        c=candelarioAB()
        if(c=="out")
        {
          bottom9="tied"
        }else if (c=="hr")
        {
          bottom9="3"
        }else if (c=="1b")
        {
          bottom9="1"
        }
      }else if (s=="2b"|s=="3b")
      {
        bottom9="2"
      }
  }else if(g=="hr")  #if grossman goes yard
  {
    bottom9= "1"
  }else if(g=="2b"|g=="3b")  #if grossman doubles or triples 
  {
    s=shortAB()
    if (s=="out")
    {
      bottom9="tied"
    }else if(s=="hr")
    {
      bottom9="2"
    }else if(s=="2b" | s=="1b")
    {
      bottom9="1"
    }
  }else #Grossman walks
  {
    #I will use the results from the other simulation since its the same situation
    temp=runif(1,0,100)
    if(temp<85.8)
    {
      bottom9="none"
    }else if(temp<93)
    {
      bottom9="tied"
    }else if(temp<95)
    {
      bottom9="1"
    }else if(temp<98)
    {
      bottom9="2"
    }else
    {
      bottom9="3"
    }
  }
  results[i]=bottom9
    i=i+1
}

If the Cardinals don’t walk Grossman, the following numbers represent out of 10,000 trials, the number of times they will win in the top of the ninth, go to the bottom of the ninth tied, down one, down two, and down three, respectively

#The score going into bottom 9 without the walk.  Out of 10,000 trials

#Cardinals win
sum(results=="none")
## [1] 78149
#Tied
sum(results=="tied")
## [1] 16191
#Cardinals down 1
sum(results=="1")
## [1] 4298
#Cardinals down 2
sum(results=="2")
## [1] 1012
#Cardinals down 3
sum(results=="3")
## [1] 351
#Simulating the game if the Cards walk Grossman to get to Short
cards=0
tigers=0
i=1
results_with_walk=list()
while (i<100002)
{
             #short gets out
  s=shortAB()
  if(s=="out")
  {
    bottom9_with_walk="none"
  }else if (s=="1b")   #if Short singles
  {
    c=candelarioAB()
    if (c=="out")
    {
      bottom9_with_walk="tied"
    }else if(c=="hr")
    {
      bottom9_with_walk="3"
    }else if(c=="2b")
    {
      #I am going to truncate the problem and say that the runner scores half from first 1/3 of the time.
      temp=runif(1,0,3)  #the first temp sees if the runner will score form first on the double
      temp2=runif(1,0,5)  # the second temp dictates the number of runs scored afterwards
      if(temp<1 & temp2<1)  #runner scores + chart
      {
        bottom9_with_walk="3"
      }else if(temp<1 & temp2>1)
      {
        bottom9_with_walk="2"
      }else if(temp>1 & temp2<1) #runner stays at third + chart
      {
        bottom9_with_walk="3"
      }else if(temp>1 & temp2>1)
      {
        bottom9_with_walk="1"
      }
    }else if(c=="3b")
      {
      temp= runif(1,0,10)
      if (temp>2.5)
      {
        bottom9_with_walk="1"
      }else
      {
        bottom9_with_walk="2"
      }
    }else if(c=="1b" | c=="bb")  #truncate problem by using chart of 1st and second 2 outs.  We make the assumtion they dont go first to third
     {
       temp=runif(1,0,100)
       if(temp<76)
       {
         bottom9_with_walk="tied"
       }else if (temp<88)
       {
         bottom9_with_walk="1"
       }else if (temp<95)
       {
         bottom9_with_walk="2"
       }else
       {
         bottom9_with_walk="3"
       }
    }
  }else if(s=="hr")  #if Short goes yard
  {
    bottom9_with_walk= "2"
  }else if(s=="2b")  #if Short doubles
  {
    c=candelarioAB()
    temp=runif(1,0,3)
    if (c=="out"&temp<1)
    {
      bottom9_with_walk="1"
    }else if(c=="out"&temp>1)
    {
      bottom9_with_walk="tied"
    }else if(c=="hr")
    {
      bottom9_with_walk="3"
    }else if(c=="2b" | c=="1b")
    {
      bottom9_with_walk="2"
    }else if (c=="bb")
    {
      temp=runif(1,0,10)
      if(temp<60)
      {
        bottom9_with_walk="tied"
      }else if(temp<76)
      {
        bottom9_with_walk="1"
      }else if(temp<87)
      {
        bottom9_with_walk="2"
      }else 
      {
        bottom9_with_walk="3"
      }
    }
  }else if (s=="bb")
  {
   c=candelarioAB()
   if(c=="out")
   {
     bottom9_with_walk="none"
   }else if(c=="1b")
   {
     bottom9_with_walk="2"
   }else if(c=="2b"|c=="3b")
   {
     bottom9_with_walk="3"
   }else if(c=="hr")
   {
     bottom9_with_walk="4"
   }else if (c=="bb")
   {
      temp=runif(1,0,10)
      if(temp<60)
      {
        bottom9_with_walk="1"
      }else if(temp<76)
      {
        bottom9_with_walk="2"
      }else if(temp<87)
      {
        bottom9_with_walk="3"
      }else 
      {
        bottom9_with_walk="4"
      }
    }
  }
  results_with_walk[i]=bottom9_with_walk
    i=i+1
}

If the Cardinals walk Grossman, the following numbers represent out of 10,000 trials, the number of times they will win in the top of the ninth, go to the bottom of the ninth tied, down one, down two, down three, and down four respectively

#The score going into bottom 9 with the walk.  Out of 10,000 trials

#Cardinals win 
sum(results_with_walk=="none")
## [1] 85147
#Game is tied
sum(results_with_walk=="tied")
## [1] 7560
#Cardinals down 1
sum(results_with_walk=="1")
## [1] 2335
#Cardinals down 2
sum(results_with_walk=="2")
## [1] 3938
#Cardinals down 3
sum(results_with_walk=="3")
## [1] 645
#Cardinals down 4
sum(results_with_walk=="4")
## [1] 376

So which is better? If you choose to pitch to pitch to Grossman you play the bottom of the ninth inning much more, however you don’t go down by two three or four nearly as much. Using a run chart we sampled the rest of the game to get more finalized results.

# we now use the run predicting table to simulate the bottom of the ninth and extra innings if needed. 
cards_win=0
tigers_win=0
bottom9_runs = 0
i=1
while (i<length(results))
{
  temp=runif(1,0,100)
  coin_flip=runif(1,0,2)
  if(temp<72)
  {
    bottom9_runs=0
  }else if(bottom9_runs<87)
  {
    bottom9_runs=1
  }else if(bottom9_runs<94)
  {
    bottom9_runs=2
  }else if(bottom9_runs<98)
  {
    bottom9_runs=3
  }else
  {
    bottom9_runs=4
  }
  if(results[i]=="none")
  {
    cards_win=cards_win+1
  }else if(results[i]=="tied")
  {
    if(bottom9_runs==0 & coin_flip<1)
    {
      tigers_win=tigers_win+1
    }else
    {
      cards_win=cards_win+1
    }
  }else if (results[i]=="1")
  {
    if(bottom9_runs==0)
    {
      tigers_win=tigers_win+1
    }else if(bottom9_runs==1)
    {
      if (coin_flip<1)
      {
        tigers_win=tigers_win+1
      }else
      {
         cards_win=cards_win+1
      }
    }else
    {
      cards_win=cards_win+1
    }
  }else if (results[i]=="2")
  {
    if( bottom9_runs<2)
    {
      tigers_win=tigers_win+1
    }else if(bottom9_runs==2)
    {
      if (coin_flip<1)
      {
        tigers_win=tigers_win+1
      }else
      {
         cards_win=cards_win+1
      }
    }else
    {
      cards_win=cards_win+1
    }
  }else if (results[i]=="3")
  {
    if( bottom9_runs<3)
    {
      tigers_win=tigers_win+1
    }else if(bottom9_runs==3)
    {
      if (coin_flip<1)
      {
        tigers_win=tigers_win+1
      }else
      {
         cards_win=cards_win+1
      }
    }else
    {
      cards_win=cards_win+1
    }
  }else
  {
    tigers_win=tigers_win+1
  }
i=i+1  
}

The following numbers represent the Cardinals record after pitching to Grossman (top wins, bottom losses)

cards_win
## [1] 89182
tigers_win
## [1] 10818
# we now use the run predicting table to simulate the bottom of the ninth and extra innings if needed. 
cards_win=0
tigers_win=0
i=1
while (i<length(results_with_walk))
{
  temp=runif(1,0,100)
  coin_flip=runif(1,0,2)
  if(temp<72)
  {
    bottom9_runs=0
  }else if(bottom9_runs<87)
  {
    bottom9_runs=1
  }else if(bottom9_runs<94)
  {
    bottom9_runs=2
  }else if(bottom9_runs<98)
  {
    bottom9_runs=3
  }else
  {
    bottom9_runs=4
  }
  if(results_with_walk[i]=="none")
  {
    cards_win=cards_win+1
  }else if(results_with_walk[i]=="tied")
  {
    if(bottom9_runs==0&coin_flip<1)
    {
      tigers_win=tigers_win+1
    }else
    {
      cards_win=cards_win+1
    }
  }else if (results_with_walk[i]=="1")
  {
    if(bottom9_runs==0)
    {
      tigers_win=tigers_win+1
    }else if(bottom9_runs==1)
    {
      if (coin_flip<1)
      {
        tigers_win=tigers_win+1
      }else
      {
         cards_win=cards_win+1
      }
    }else
    {
      cards_win=cards_win+1
    }
  }else if (results_with_walk[i]=="2")
  {
    if( bottom9_runs<2)
    {
      tigers_win=tigers_win+1
    }else if(bottom9_runs==2)
    {
      if (coin_flip<1)
      {
        tigers_win=tigers_win+1
      }else
      {
         cards_win=cards_win+1
      }
    }else
    {
      cards_win=cards_win+1
    }
  }else if (results_with_walk[i]=="3")
  {
    if( bottom9_runs<3)
    {
      tigers_win=tigers_win+1
    }else if(bottom9_runs==3)
    {
      if (coin_flip<1)
      {
        tigers_win=tigers_win+1
      }else
      {
         cards_win=cards_win+1
      }
    }else
    {
      cards_win=cards_win+1
    }
  }else
  {
    tigers_win=tigers_win+1
  }
i=i+1  
}

The following numbers represent the Cardinals record walking Grossman Grossman (top wins, bottom losses)

cards_win
## [1] 90315
tigers_win
## [1] 9685

Conclusion: My simulation suggests that the right play in this situation is to walk Grossman intentionally. This makes sense as the drop in batting production is significant enough between Grossman and Short that it overcomes the extra baserunner. In my time playing baseball I have heard coaches say things like “never put the go ahead run on first” or “the winning run is 90 feet closer”. The response is that it always depends and in a situation like this, walking the batter is clearly the play that gives your team the best chance of winning.

Reflection of Method: My choice of monte carlo simulation to tackle this problem forced me to make simplifications when necessary. As we previously discussed, I did not factor in pitching at all into this simulation which is leaving out a sizeable chunk of information. Neither player had enough career at bats against the pitcher Garcia to be useful (likely due to the fact that its an interleague game). Additionally I didn’t take the players speed into account when running the bases and used league averages on plays like a runner scoring on a single from second. All models must make simplifications at some point as they are unavoidable. It is important to take note of them and think about how they may impact the model results. That being said, a simulation is one of the most thorough methods. It is computationally expensive but provides very valuable information.