Shading regions of the normal: The Stanine scale

[This article was first published on Nicebread » R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

For the presentation of norm values, often stanines are used (standard nine). These values mark a person’s relativ position in comparison to the sample or to norm values.
According to Wikipedia:

The underlying basis for obtaining stanines is that a normal distribution is divided into nine intervals, each of which has a width of 0.5 standard deviations excluding the first and last, which are just the remainder (the tails of the distribution). The mean lies at the centre of the fifth interval.

For illustration purposes, I wanted to plot the regions of the stanine values in the standard normal distribution – here’s the result:

First: Calculate the stanine boundaries and draw the normal curve:

?View Code RSPLUS

# First: Calculate stanine breaks (on a z scale)
stan.z <- c(-3, seq(-1.75, +1.75, length.out=8), 3)
# Second: get cumulative probabilities for these z values
stan.PR <- pnorm(stan.z)
# define a color ramp from blue to red (... or anything else ...)
c_ramp <- colorRamp(c("darkblue", "red"), space="Lab")
# draw the normal curve, without axes; reduce margins on left, top, and right
curve(dnorm(x,0,1), xlim=c(-3,3), ylim=c(-0.03, .45), xlab="", ylab="", axes=FALSE)

Next: Calculate the shaded regions and plot a polygon for each region:

?View Code RSPLUS

# Calculate polygons for each stanine region
# S.x = x values of polygon boundary points, S.y = y values
for (i in 1:(length(stan.z)-1)) {
	S.x  <- c(stan.z[i], seq(stan.z[i], stan.z[i+1], 0.01), stan.z[i+1])
	S.y  <- c(0, dnorm(seq(stan.z[i], stan.z[i+1], 0.01)), 0)
	polygon(S.x,S.y, col=rgb(c_ramp(i/9), max=255))

And finally: add some legends to the plot:

?View Code RSPLUS

# print stanine values in white
# font = 2 prints numbers in boldface
text(seq(-2,2, by=.5), 0.015, label=1:9, col="white", font=2)
# print cumulative probabilities in black below the curve
text(seq(-1.75,1.75, by=.5), -0.015, label=paste(round(stan.PR[-c(1, 10)], 2)*100, "%", sep=""), col="black", adj=.5, cex=.8)
text(0, -0.035, label="Percentage of sample <= this value", adj=0.5, cex=.8)

And finally, here’s a short script for shading only one region (e.g., the lower 2.5%):

?View Code RSPLUS

# draw the normal curve
curve(dnorm(x,0,1), xlim=c(-3,3), main="Normal density")
# define shaded region
from.z <- -3
to.z <- qnorm(.025)
S.x  <- c(from.z, seq(from.z, to.z, 0.01), to.z)
S.y  <- c(0, dnorm(seq(from.z, to.z, 0.01)), 0)
polygon(S.x,S.y, col="red")

To leave a comment for the author, please follow the link and comment on their blog: Nicebread » R. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)