3

Need to create a chart which looks like this: enter image description here

I'm almost there, just missing the individual points which are plotted vertically.

Here the data:

q6 <- structure(list(x1 = c(0.0629, 0.063, 0.0628, 0.0634, 0.0619, 
0.0613, 0.063, 0.0628, 0.0623, 0.0631, 0.0635, 0.0623, 0.0635, 
0.0645, 0.0619, 0.0631, 0.0616, 0.063, 0.0636, 0.064, 0.0628, 
0.0615, 0.063, 0.0635, 0.0623), x2 = c(0.0636, 0.0631, 0.0631, 
0.063, 0.0628, 0.0629, 0.0639, 0.0627, 0.0626, 0.0631, 0.063, 
0.063, 0.0631, 0.064, 0.0644, 0.0627, 0.0623, 0.063, 0.0631, 
0.0635, 0.0625, 0.0625, 0.0632, 0.0629, 0.0629), x3 = c(0.064, 
0.0622, 0.0633, 0.0631, 0.063, 0.0634, 0.0625, 0.0622, 0.0633, 
0.0633, 0.0638, 0.063, 0.063, 0.0631, 0.0632, 0.063, 0.0631, 
0.0626, 0.0629, 0.0629, 0.0616, 0.0619, 0.063, 0.0635, 0.063), 
    x4 = c(0.0635, 0.0625, 0.0633, 0.0632, 0.0619, 0.0625, 0.0629, 
    0.0625, 0.063, 0.0631, 0.0635, 0.0627, 0.063, 0.064, 0.0622, 
    0.0628, 0.062, 0.0629, 0.0635, 0.0635, 0.062, 0.0619, 0.0631, 
    0.0631, 0.0626), x5 = c(0.064, 0.0627, 0.063, 0.0633, 0.0625, 
    0.0628, 0.0627, 0.0627, 0.0624, 0.063, 0.0633, 0.0629, 0.063, 
    0.0642, 0.0635, 0.0629, 0.0625, 0.0628, 0.0634, 0.0634, 0.0623, 
    0.0622, 0.063, 0.0633, 0.0628)), .Names = c("x1", "x2", "x3", 
"x4", "x5"), class = "data.frame", row.names = c(NA, -25L))

Here is the code:

range_span <- function(x) return(diff(range(x))) # function to calculate range
# q6 <- read.table(file="/Users/.../blah.csv",header=T,sep=",") #data
medians <- apply(q6,1,median) 
ranges <- apply(q6,1,range_span)
centre <- mean(medians) #grand median
Rtilde <- median(ranges) #median of ranges

plot(medians, type="b",xaxp=c(1, 25, 24),pch=19,xlab="Sample No.",ylab="Medians",main="Median Chart for Thickness of Metal Parts")

# code below draws the control limits 

action.limits<-c(centre+0.681*Rtilde,centre-0.681*Rtilde)
warn.limits<-c(centre+(2/3)*0.681*Rtilde,centre-(2/3)*0.681*Rtilde)

abline(h = centre, lty = 3, col = "black")  
v0 <-c("CL") 
mtext(side = 4, text = v0, at = centre, col = "black", las=2)

abline(h = warn.limits, lty = 3, col = "blue") 
v1 <-c("UWL","LWL") 
mtext(side = 4, text = v1, at = warn.limits, col = "blue", las=2) 

abline(h = action.limits, lty = 3, col = "black") 
v2 <-c("UCL","LCL") # the labels for action.limits
mtext(side = 4, text = v2, at = action.limits, col = "black", las=2)

I'm sure there's an easy solution, I'm not experienced at all with R I just wanted to set myself a challenge by producing the chart in R for a coursework but now I'm starting to run out of time.

  • Could points() help? I need R to recognise that each row in q6 is a sample that way I could maybe do points(q6,c(1:25)) or something like that?
CanofDrink
  • 89
  • 9

1 Answers1

2

So, you don't have the x-coordinates (1 to 25) anywhere in your data, which can make plotting hard.

q6$x = 1:25

This next step isn't strictly necessary, but it makes things more convenient. I'm going to "melt" your data into a long format:

q6_long = reshape2::melt(q6, id.vars = "x")

## just showing what it looks like now
head(q6_long)
#   x variable  value
# 1 1       x1 0.0629
# 2 2       x1 0.0630
# 3 3       x1 0.0628
# 4 4       x1 0.0634
# 5 5       x1 0.0619
# 6 6       x1 0.0613

Now adding points is easy with the points function:

points(q6_long$x, q6_long$value, pch = 5)

enter image description here

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • Thank you! I literally just made an edit suggesting to use `points` and 1:25, I just didn't know how to implement it. Could you explain what the melting part is and why it's needed? – CanofDrink Jan 22 '16 at 19:46
  • 1
    `melt` moves your data from wide - format (you have many columns that you want to put on the y axis) to long format (everything number that goes on the y axis is in one column). Run the command (you may need to install the `reshape2` package first) and look at the data after melting - you'll probably see what it does better than I can explain it. – Gregor Thomas Jan 22 '16 at 19:50
  • 1
    Melting is nice because I can do a single `points()` call - if I didn't melt I would need to do a `for` loop (or an `apply` or something) to plot the x1 column, then the x2 column, then the x3 column, etc. The `melt` combined all of those values into one column, so one `points()` call does everything at once. – Gregor Thomas Jan 22 '16 at 19:51