棒球模拟

时间:2019-03-27 03:30:45

标签: r loops while-loop simulation

我正在尝试创建一个模拟,在该模拟中,棒球运动员基于这些给定的概率(Base = .32和Out = .68)进入或退出。当他没有出局时,他有0.2%的机会命中全垒打。他可以随意打球。但是一旦他有40次出局,模拟就会停止。我想知道该球员在上述条件下会获得多少本垒打。

我创建了一个函数,可以给我上面想要的东西。但是一旦有40个出局,它就不会停止。我觉得while循环会有所帮助,但我对它们不太熟悉。任何其他技巧也将有所帮助。我是R的新手。

Player = function(n) {
 x = sample(c("Out","Base"), n , prob = c(.68,.32) ,replace = TRUE)
 hit_sum = sum(x =="Base")*.20
 out_sum = sum(x =="Out")
 return(hit_sum)
}



new = Player(70)
new

这仅使我从70个样本中获得了多少本垒打。while循环是否会以某种方式应用于上述代码?谢谢。

4 个答案:

答案 0 :(得分:2)

这里是一个稍微修改的功能。

n_homerun <- function(N = 100, p_homerun = 0.2) {
    x <- sample(c("Base", "Out"), N, replace = TRUE, prob = c(0.32, 0.68))

    maxN <- which(cumsum(x == "Out") == 40)[1]
    if (length(maxN) == 0)
        stop("Sample has less than 40 Out's, increase N.")

    round(sum(x[1:maxN] == "Base") * p_homerun)
}

我们现在可以使用replicate生成本垒打的经验分布

Nrep <- 10000
res <- replicate(Nrep, n_homerun(), simplify = TRUE)

让我们绘制分布图

library(tidyverse)
data.frame(res = res) %>%
    count(res) %>%
    mutate(freq = n / Nrep) %>%
    ggplot(aes(res, freq)) +
    geom_col() +
    scale_x_continuous(breaks = 1:10)

enter image description here

答案 1 :(得分:0)

当样本中的“ Outs”达到40个时,您可以将x设为子集。尝试将功能更改为

Player = function(n) {
    x = sample(c("Out","Base"), n , prob = c(.68,.32) ,replace = TRUE)
    inds <- cumsum(x == "Out") >= 40
    if (any(inds)) 
      x <- x[1:which.max(inds)]
    hit_sum = sum(x =="Base")*.20
    out_sum = sum(x =="Out")
    return(hit_sum)
}

答案 2 :(得分:0)

#I am also new with "R".   Browsing the internet, I came across this paper by Cal 
#Morris.

http://www.stat.harvard.edu/People/Faculty/Carl_N._Morris/Carl_N._Morris_Sports_Articles/Runs_per_Game_Paper_(Short%20Version).txt

#I was trying to compute the game by hand, then realized I could make an "R"  
#program.

#Here it is
#######################
#Walking Team*
H=0
D=0
T=0
HR=0
SAC=0
BB=20.33383331
AB=27
PA= AB + BB

OBA=(H+BB)/PA




PA= AB + BB

P0= (1-OBA)^3
P1=3*OBA*(1-OBA)^3
P2=6*OBA^2*(1-OBA)^3
P3=1-P1-P2


hr =HR/(H +BB)
w= BB/(H +BB)
d= D/(H +BB)
t=T/(H +BB)
s=1-hr-w-d-t
d1= .576*d
d2=.424d
s1=.324*s
s2=.412*s
s3=.264*s
L1= 1-hr
L2=L1*w +(w+s)*(s + d1) +d*s1
L3= L2*w +((w+s)*(w+s1+s2) +d*w)*s1
LOB =(1-P0)*L1 +(1-P0-P1)*L2+(1-P0-P1-P2)*L3

Eruns=3*OBA/(1-OBA) 
9*(Eruns-LOB)          #averages 4.5 runs per game.

#Just play around with singles, doubles, triples, HRs to get the number of runs per 
#game you want. 31.5 at bats, 4.5 home runs per game, the rest outs will also get you 
#4.5 runs #per game, or 10.003816 singles, everything else zero will get 4.5 runs per 
#game. 

答案 3 :(得分:0)

 #Updating my prior respose, I'm sure you want a random number of runs per inning, 
 #based on probability.  I found this program for half an inning, 
 #https://gist.github.com/bayesball/36fba464d294944268f09630aa65ab61
 #I replaced "prob" line with 
prob <- c(27,0,0,0,0,4.3)   # inputs  in parenthesis are (outs, bases on 
 #balls, singles, doubles, triples, home runs) 

#I added the following to the online 1/2 inning program

st <- runs_setup()
R <- replicate(99999, simulate_half_inning(st))  # for complete 9 inning game make 
#number in parenthesis divisible by 9.  I picked 99999
round(prop.table(table(R)), 6)


b<-matrix(R,11111,9)   # this divides the 99999 random innings into 11111 games
hrteam<-apply(b,1,sum)
round(prop.table(table(hrteam)),6)

graph<-round(prop.table(table(hrteam)),6)