Skip to content

Instantly share code, notes, and snippets.

@bayesball
Created June 19, 2016 12:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bayesball/36fba464d294944268f09630aa65ab61 to your computer and use it in GitHub Desktop.
Save bayesball/36fba464d294944268f09630aa65ab61 to your computer and use it in GitHub Desktop.
Functions to Simulate a Half-Inning of Baseball
# to simulate the number of runs in one half-inning
# st <- runs_setup()
# simulate_half_inning(st)
runs_setup <- function(){
# based on 2015 season data
Prob_Single <- matrix(0, 8, 8)
dimnames(Prob_Single)[[1]] <- c("000", "100", "010", "001",
"110", "101", "011", "111")
dimnames(Prob_Single)[[2]] <- c("000", "100", "010", "001",
"110", "101", "011", "111")
Prob_Single["000", "100"] <- 1
Prob_Single["100", c("101", "110")] <-
round(c(1411, 3940) / (1411 + 3940), 3)
Prob_Single["010", c("100", "101")] <-
round(c(1044, 768) / (1044 + 768), 3)
Prob_Single["001", "100"] <- 1
Prob_Single["110", c("101", "110", "111")] <-
round(c(403, 605, 675) / (403 + 605 + 675), 3)
Prob_Single["101", c("101", "110")] <-
round(c(178, 583) / (178 + 583), 3)
Prob_Single["011", c("100", "101")] <-
round(c(215, 200) / (215 + 200), 3)
Prob_Single["111", c("101", "110", "111")] <-
round(c(137, 211, 266) / (137 + 211 + 266), 3)
Prob_Double <- matrix(0, 8, 8)
dimnames(Prob_Double)[[1]] <- c("000", "100", "010", "001",
"110", "101", "011", "111")
dimnames(Prob_Double)[[2]] <- c("000", "100", "010", "001",
"110", "101", "011", "111")
Prob_Double[c("000", "010", "001", "011"), "010"] <- 1
Prob_Double["100", c("011", "010")] <-
round(c(817, 591) / (817 + 591), 3)
Prob_Double["110", c("010", "011")] <-
round(c(212, 260) / (212 + 260), 3)
Prob_Double["101", c("010", "011")] <-
round(c(107, 132) / (107 + 132), 3)
Prob_Double["111", c("010", "011")] <-
round(c(74, 95) / (74 + 95), 3)
Prob_Walk <- matrix(0, 8, 8)
dimnames(Prob_Walk)[[1]] <- c("000", "100", "010", "001",
"110", "101", "011", "111")
dimnames(Prob_Walk)[[2]] <- c("000", "100", "010", "001",
"110", "101", "011", "111")
Prob_Walk["000", "100"] <- 1
Prob_Walk["100", "110"] <- 1
Prob_Walk["010", "110"] <- 1
Prob_Walk["001", "101"] <- 1
Prob_Walk[c("110", "101", "011", "111"), "111"] <- 1
# outcomes are out, walk, single, double, triple, home run
prob <- c(86304 + 37446, 13122 + 951 + 1602,
28016, 8241, 939, 4909)
prob <- prob / sum(prob)
names(prob) <- c("OUT", "BB", "1B", "2B", "3B", "HR")
list(Prob_Single=Prob_Single, Prob_Double=Prob_Double,
Prob_Walk=Prob_Walk, prob=prob)
}
simulate_half_inning <- function(setup){
runs.transition <- function(s1, s2){
before <- sum(as.numeric(unlist(strsplit(s1, split=""))))
after <- sum(as.numeric(unlist(strsplit(s2, split=""))))
before - after + 1
}
outs <- 0
bases <- "000"
runs <- 0
all_bases <- c("000", "100", "010", "001",
"110", "101", "011", "111")
while(outs < 3){
event <- sample(names(setup$prob), size=1, prob=setup$prob)
if (event=="1B") new_bases <- sample(all_bases, 1,
prob=setup$Prob_Single[bases, ])
if (event=="2B") new_bases <- sample(all_bases, 1,
prob=setup$Prob_Double[bases, ])
if (event=="BB") new_bases <- sample(all_bases, 1,
prob=setup$Prob_Walk[bases, ])
if (event=="3B") new_bases <- "001"
if (event=="HR") new_bases <- "000"
if (event=="OUT") new_bases <- bases
outs <- outs + (event == "OUT")
runs <- runs - (event == "OUT") +
runs.transition(bases, new_bases)
bases <- new_bases
}
runs
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment