Introduction

This is an RMarkdown document displaying R code for generating plots that visualize power of a one-sample Z-test. The plots are intended to demonstrate how the value of power changes due to a number of different factors.

The null hypothesis distribution assumes a normal distribution with a mean of 200. The factors considered are effect size, significance level, sample size, standard deviation, and one-tailed vs. two-tailed testing.

This was created with the intention of supplementing lecture notes regarding factors affecting power.

Loading the appropriate packages

The first block of code loads the appropriate R packages.

library(ggplot2)
library(dplyr)
library(gridExtra)

The Relationship Between Power and Effect Size

The first of five plots visualizing power focuses on effect size as a factor of power. Three different effect sizes are considered, and a plot with two density curves overlayed is created for each. In each plot, the rejection region was calculated (same for all three cases). The density curve corresponding to the true effect size is then partially shaded in. The portion shaded is only that which is contained in the rejection region. The proportion of the density curve shaded in is equivalent to power, and documented at the top of each plot. Subsequent power plots will follow this structure.

e1 <- ggplot(data.frame(x = c(160, 300)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 300, 10),
                              limits=c(160, 300)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("20 Point Effect Size; Power = .637") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 10)
    y[x < 216.5] <- NA
    return(y)
}
e1 <- e1 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

e2 <- ggplot(data.frame(x = c(160, 300)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(230, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 300, 10),
                              limits=c(160, 300)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("30 Point Effect Size; Power = .911") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 230, sd = 10)
    y[x < 216.5] <- NA
    return(y)
}
e2 <- e2 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

e3 <- ggplot(data.frame(x = c(160, 300)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(250, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 300, 10),
                              limits=c(160, 300)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("50 Point Effect Size; Power = 1.00 (Approximately)") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 250, sd = 10)
    y[x < 216.5] <- NA
    return(y)
}
e3 <- e3 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

grid.arrange(e1,e2,e3,ncol=1)

The Relationship Between Power and Significance Level

The second of five plots visualizing power focuses on significance level as a factor of power. Three different signifiance levels are considered. In each plot, the rejection region was calculated.

a1 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("Alpha = .10; Power = .764") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 10)
    y[x < 212.8] <- NA
    return(y)
}
a1 <- a1 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

a2 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("Alpha = .05; Power = .637") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 10)
    y[x < 216.5] <- NA
    return(y)
}
a2 <- a2 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

a3 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("Alpha = .01; Power = .371") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 10)
    y[x < 223.3] <- NA
    return(y)
}
a3 <- a3 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

grid.arrange(a1,a2,a3,ncol=1)

The Relationship Between Power and Sample Size

The third of five plots visualizing power focuses on sample size as a factor of power. Three different sample sizes are considered. In each plot, the rejection region was calculated.

n1 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("n = 16; Power = .637") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 10)
    y[x < 216.5] <- NA
    return(y)
}
n1 <- n1 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

n2 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 8),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 8),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("n = 25; Power = .802") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 8)
    y[x < 213.2] <- NA
    return(y)
}
n2 <- n2 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

n3 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 4),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 4),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("n = 100; Power = 1.00 (Approximately)") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 4)
    y[x < 206.6] <- NA
    return(y)
}
n3 <- n3 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

grid.arrange(n1,n2,n3,ncol=1)

The Relationship Between Power and Standard Deviation

The fourth of five plots visualizing power focuses on standard deviation as a factor of power. Three different standard deviation are considered. In each plot, the rejection region was calculated.

s1 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("Standard deviation = 50; Power = .637") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 10)
    y[x < 216.5] <- NA
    return(y)
}
s1 <- s1 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

s2 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 8),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 8),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("Standard deviation = 40; Power = .802") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 8)
    y[x < 213.2] <- NA
    return(y)
}
s2 <- s2 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

s3 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 4),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 4),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("Standard deviation = 20; Power = 1.00 (Approximately)") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 4)
    y[x < 206.6] <- NA
    return(y)
}
s3 <- s3 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

grid.arrange(s1,s2,s3,ncol=1)

The Relationship Between Power and One-tailed vs. Two-tailed Testing

The last plot visualizing power focuses on number of tails in a hypothesis test. Both one-tailed and two-tailed testing cases are considered. In each plot, the rejection region was calculated.

t1 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("One-tailed; Power = .637") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 10)
    y[x < 216.5] <- NA
    return(y)
}
t1 <- t1 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

t2 <- ggplot(data.frame(x = c(160, 260)), aes(x = x)) +
        stat_function(fun = dnorm, args = list(200, 10),
                      colour = "black") +
        stat_function(fun = dnorm, args = list(220, 10),
                      colour = "dodgerblue3") +
        scale_x_continuous(name = "Score",
                              breaks = seq(160, 260, 10),
                              limits=c(160, 260)) +
        scale_y_continuous(name = "Frequency") +
        ggtitle("Two-tailed; Power = .516") + theme(plot.title = element_text(hjust = 0.5))
funcShaded <- function(x) {
    y <- dnorm(x, mean = 220, sd = 10)
    y[x < 219.6 & x > 180.4] <- NA
    return(y)
}
t2 <- t2 + stat_function(fun=funcShaded, geom="area", fill="dodgerblue3", alpha=0.2)

grid.arrange(t1,t2,ncol=1)