library(purrr)
library(stringr)
We already observed all \(k = 20\) successes in \(n = 20\) jobs in a day. Under \[ H_0: p = p_0 = 0.92 , \] the p-value is given by the probability of seeing an outcome at least as extreme as 20 successes in 20 jobs. Note that \[ H_A: p > p_0 = 0.92 , \] to have an desired outcome, we want \[\begin{align*} pv = & P (X \geq k) \\ = & 1 - P (X < k) \\ = & 1 - P (X \leq k - 1) \\ = & \sum_{i = k} ^ {n} \binom{n}{i} p_0 ^ {i} (1 - p_0) ^ {n - i} \\ = & \sum_{i = 20} ^ {20} \binom{20}{i} 0.92 ^ {i} (1 - 0.92) ^ {20 - i} \\ = & 0.92 ^ {20} \\ = & 0.1886933 . \end{align*}\]
n <- 20
k <- 20
p0 <- 0.92
### p-value. Be careful about (k - 1)
pbinom(q = k - 1, size = n, prob = p0, lower.tail = FALSE)
[1] 0.1886933
### p-value. Be careful about (k - 1)
1 - pbinom(q = k - 1, size = n, prob = p0)
[1] 0.1886933
### Special case here
dbinom(k, size = n, prob = p0)
[1] 0.1886933
### Discretize the candidate p0
p0Vec <- seq(0, 1, length.out = 10001)
alp <- 0.05
### Method 1: pbinom supports vector input
pvVec <- 1 - pbinom(q = k - 1, size = n, prob = p0Vec)
### Interval esimate
c(Lower = p0Vec[min(which(pvVec > alp))], Upper = p0Vec[max(which(pvVec > alp))])
Lower Upper
0.8609 1.0000
### Method 2:
### Compute p-value across p0Vec
pvVec <- map_dbl(p0Vec, function(p0){
1 - pbinom(q = k - 1, size = n, prob = p0)
})
### Interval esimate
c(Lower = p0Vec[min(which(pvVec > alp))], Upper = p0Vec[max(which(pvVec > alp))])
Lower Upper
0.8609 1.0000
### Remember to specify the alternative correctly
binom.test(x = k, n = n, p = p0, alternative = "greater")
Exact binomial test
data: k and n
number of successes = 20, number of trials = 20, p-value = 0.1887
alternative hypothesis: true probability of success is greater than 0.92
95 percent confidence interval:
0.8608917 1.0000000
sample estimates:
probability of success
1
The ouput agrees with part a and b.
mu1Vec <- c(5, 5)
mu2Vec <- c(5, 5.5)
mudiff <- 0
n <- 50
sd <- sqrt(1)
alp <- 0.05
nSim <- 1000
### For two scenarios
outQ2a <- map2_dbl(mu1Vec, mu2Vec, function(mu1, mu2) {
### Repeat the experiment and output logical vector
I <- map_lgl(seq_len(nSim), function(iSim) {
### Generate data sets
X1 <- rnorm(n, mean = mu1, sd = sd)
X2 <- rnorm(n, mean = mu2, sd = sd)
### 95% two-sided confidence interval
CI <- t.test(X1, X2, alternative = "two.sided", mu = mudiff, conf.level = 1 - alp)$conf.int
### Check if 0 is not covered in the CI
### TRUE if not covered
(mudiff < CI[1]) | (mudiff > CI[2])
})
### Compute the proportion
sum(I) / nSim
})
names(outQ2a) <- str_c("Scenario ", 1:2)
outQ2a
Scenario 1 Scenario 2
0.042 0.681
(Not graded)
### Method 1:
nby <- 5
### For two scenarios
outQ2b <- map2_dbl(mu1Vec, mu2Vec, function(mu1, mu2) {
### Repeat the experiment and output logical vector
I <- map_lgl(seq_len(nSim), function(iSim) {
n0 <- 0
X1 <- NULL
X2 <- NULL
while (TRUE) {
### Current number in each group
n0 <- n0 + nby
### Check if the number exceed the limit
if (n0 > n) {
break
}
### Combine data sets
X1 <- c(X1, rnorm(nby, mean = mu1, sd = sd))
X2 <- c(X2, rnorm(nby, mean = mu2, sd = sd))
### 95% two-sided confidence interval
CI <- t.test(X1, X2, alternative = "two.sided", mu = mudiff, conf.level = 1 - alp)$conf.int
### Check if 0 is not covered in the CI
### TRUE if not covered
Ireject <- (mudiff < CI[1]) | (mudiff > CI[2])
if (Ireject) {
break
}
}
Ireject
})
### Compute the proportion
sum(I) / nSim
})
names(outQ2b) <- str_c("Scenario ", 1:2)
outQ2b
Scenario 1 Scenario 2
0.195 0.804
### For two scenarios
outQ2b <- map2_dbl(mu1Vec, mu2Vec, function(mu1, mu2) {
### Repeat the experiment and output logical vector
I <- map_lgl(seq_len(nSim), function(iSim) {
### Generate data sets
X1 <- rnorm(n, mean = mu1, sd = sd)
X2 <- rnorm(n, mean = mu2, sd = sd)
### Index for subsequence
Isub <- map(seq(5, n, by = nby), seq_len)
### Indicator for reject the null hypothesis
Ireject <- map_lgl(Isub, function(i) {
### 95% two-sided confidence interval for all subsequences
CI <- t.test(X1[i], X2[i], alternative = "two.sided", mu = mudiff, conf.level = 1 - alp)$conf.int
### Check if 0 is not covered in the CI
### TRUE if not covered
(mudiff < CI[1]) | (mudiff > CI[2])
})
### Check if null is reject
sum(Ireject) != 0
})
### Compute the proportion
sum(I) / nSim
})
names(outQ2b) <- str_c("Scenario ", 1:2)
outQ2b
Scenario 1 Scenario 2
0.212 0.792
### Method 2:
nby <- 5
### For two scenarios
outQ2b <- map2_dbl(mu1Vec, mu2Vec, function(mu1, mu2) {
### Repeat the experiment and output logical vector
I <- map_lgl(seq_len(nSim), function(iSim) {
### Generate data sets
X1 <- rnorm(n, mean = mu1, sd = sd)
X2 <- rnorm(n, mean = mu2, sd = sd)
### Index for subsequence
Isub <- map(seq(5, n, by = nby), seq_len)
### Indicator for reject the null hypothesis
Ireject <- map_lgl(Isub, function(i) {
### 95% two-sided confidence interval for all subsequences
CI <- t.test(X1[i], X2[i], alternative = "two.sided", mu = mudiff, conf.level = 1 - alp)$conf.int
### Check if 0 is not covered in the CI
### TRUE if not covered
(mudiff < CI[1]) | (mudiff > CI[2])
})
### Check if null is reject
sum(Ireject) != 0
})
### Compute the proportion
sum(I) / nSim
})
names(outQ2b) <- str_c("Scenario ", 1:2)
outQ2b
Scenario 1 Scenario 2
0.176 0.804
(Not graded)
The type I error is given as \[ P (\text{Type I error}) = P (\text{Reject } H_0 \mid H_0 \text{ is TRUE}) , \] which is the proportion we obtained under scenario 1. That means we have type I error 0.042 for standard experiment and 0.176 for Scenario 2. For sequential experiments, we have more chances to reject \(H_0\) compared with standard experiments, as we test for every \(5\) subjects. So we are more likely to conduct type I error, which means the test is over-liberal. Hence, to obtain the desired nominal level, we should better use standard experiment.
nSim <- 100
alp <- 0.05
nVec <- c(10, 50, 100, 200)
pVec <- c(0.01, 0.1, 0.5)
### Experiment with different n
outQ3 <- map(nVec, function(n) {
### Experiment with different p
map(pVec, function(p){
### X ~ Bin (n, p)
X <- rbinom(n = nSim, size = n, prob = p)
### T
T <- sqrt(n) * ((X / n) - p)
### KS test
### Ignore the warnings here
ks <- ks.test(T, pnorm, mean = 0, sd = sqrt(p * (1 - p)))
### Compare p-value with alpha
### If TRUE, reject the null hypothesis that two distributions equal
ks$p.value <= alp
})
})
### Combine as a matrix
outQ3 <- do.call(rbind, outQ3)
dimnames(outQ3) <- list(str_c("size = ", nVec), str_c("prob = ", pVec))
outQ3
prob = 0.01 prob = 0.1 prob = 0.5
size = 10 TRUE TRUE TRUE
size = 50 TRUE TRUE FALSE
size = 100 TRUE TRUE FALSE
size = 200 TRUE FALSE TRUE
The conclusion would be made accordingly, that is, if we have TRUE
, we have sufficient evidence to reject the null and conclude that two distributions are different, otherwise, we do not have sufficient evidence to reject the null and conclude that it is plausible that two distributions are the same.
(Not graded)
nSim <- 100
n <- 8000
side <- 10000
alp <- 0.05
### Repeat the experiment
EVec <- map_dbl(seq_len(nSim), function(iSim) {
### Generate data from the square
X <- matrix(runif(2 * n, min = 0, max = side), ncol = 2)
colnames(X) <- c("x", "y")
### Compute different combinations of distances
dis <- dist(X)
### Compute D, the minimum distance
D <- min(dis)
### Compute E
E <- 1 - exp(-D^2 / 0.995)
E
})
### Compare p-value with alpha
### If TRUE, reject the null hypothesis that two distributions equal
ks.test(EVec, punif)$p.value <= alp
[1] FALSE
FALSE here means we do NOT have sufficient evidence to reject the null hypothesis that two distributions equal, which means \(E\) is plausible to be uniform on \([0, 1]\).
(Not graded)
n <- 200
lam1 <- 1/2
lam2 <- 1/30
T <- seq(0, 120, length.out = 10000)
### Simulate the waiting time
tW <- rexp(n, rate = lam1)
### Simulate the time spent
tS <- rexp(n, rate = lam2)
### Compute the arrival time
tA <- cumsum(tW)
### Compute the departure time
tD <- tA + tS
### Over the first 120 minutes
nC <- map_dbl(T, function(t){
### Number of customer in the restaurant
sum((tA < t) & (tD > t))
})
### Plot the number of customers in the restaurant over the first 120 minutes after the restaurant opens
plot(T, nC, type = "l", xlab = "Time (min)", ylab = "Number of customers", main = "The number of customers over the first 120 minutes.")
nSim <- 1000
TQ5bi <- c(10, 20, 30, 120)
nQ5bii <- 10
TQ5bii <- 60
nQ5biii <- 20
TQ5biii <- 60
outQ5b <- map(seq_len(nSim), function(iSim) {
### Simulate the waiting time
tW <- rexp(n, rate = lam1)
### Simulate the time spent
tS <- rexp(n, rate = lam2)
### Compute the arrival time
tA <- cumsum(tW)
### Compute the departure time
tD <- tA + tS
### Q5bi
nQ5bi <- map_dbl(TQ5bi, function(t) {
### Number of customer in the restaurant
sum((tA < t) & (tD > t))
})
### Q5bii
### Indicator, TRUE if the condition in the question is satisfied
IQ5bii <- (sum((tA < TQ5bii) & (tD > TQ5bii))) < nQ5bii
### Q5biii
### Indicator, TRUE if the condition in the question is satisfied
IQ5biii <- (sum((tA < TQ5biii) & (tD > TQ5biii))) > nQ5biii
list(nQ5bi = nQ5bi, IQ5bii = IQ5bii, IQ5biii = IQ5biii)
})
### Compute the average number
colMeans(do.call(rbind, map(outQ5b, `[[`, "nQ5bi")))
[1] 4.286 7.429 9.644 14.848
### Compute the proportion
sum(map_lgl(outQ5b, `[[`, "IQ5bii")) / nSim
[1] 0.15
### Compute the proportion
sum(map_lgl(outQ5b, `[[`, "IQ5biii")) / nSim
[1] 0.021