# How to use boxplots to find the point where values are more likely to come from different conditions?

I have plotted some data using box plots. I am comparing Condition 1 (left) and Condition 2 (Right) values. My aim is to find a point at which we make a decision where the value changes from point Condition 1 to Condition 2.

Will this conclusion make sense, if I say if I do the experiment again and get any value than the median of Condition 1, then it is likely that the value will be of Condition 2?

Or is there any other way which I can represent this data to to get conclusion that if I get random value I can say if it is from condition 1 or condition 2?

Data presented as code for R input:

Cond.1 <- c(2.9, 3.0, 3.1, 3.1, 3.1, 3.3, 3.3, 3.4, 3.4, 3.4, 3.5, 3.5, 3.6, 3.7, 3.7,
3.8, 3.8, 3.8, 3.8, 3.9, 4.0, 4.0, 4.1, 4.1, 4.2, 4.4, 4.5, 4.5, 4.5, 4.6,
4.6, 4.6, 4.7, 4.8, 4.9, 4.9, 5.5, 5.5, 5.7)
Cond.2 <- c(2.3, 2.4, 2.6, 3.1, 3.7, 3.7, 3.8, 4.0, 4.2, 4.8, 4.9, 5.5, 5.5, 5.5, 5.7,
5.8, 5.9, 5.9, 6.0, 6.0, 6.1, 6.1, 6.3, 6.5, 6.7, 6.8, 6.9, 7.1, 7.1, 7.1,
7.2, 7.2, 7.4, 7.5, 7.6, 7.6, 10, 10.1, 12.5)


Each condition has 39 values.

@NickCox has presented a good way to visualize your data. I take it you want to find a rule for deciding when to classify a value as condition1 vs condition2.

In an earlier version of your question, you wondered if you should call any value greater than the median of condition1 as a member of condition2. This is not a good rule to use. Note that by definition, $$50\%$$ of a distribution is above the median. Therefore, you will necessarily misclassify $$50\%$$ of true condition1 members. Based on your data, I gather you will also misclassify $$18\%$$ of your true condition2 members.

A way to think through the value of a rule like yours is to form a confusion matrix. In R, you can use ?confusionMatrix in the caret package. Here is an example using your data and your suggested rule:

library(caret)

dat  = stack(list(cond1=Cond.1, cond2=Cond.2))
pred = ifelse(dat$$values>median(Cond.1), "cond2", "cond1") confusionMatrix(pred, dat$$ind)
# Confusion Matrix and Statistics
#
#           Reference
# Prediction cond1 cond2
#      cond1    20     7
#      cond2    19    32
#
#                Accuracy : 0.6667
# ...
#
#             Sensitivity : 0.5128
#             Specificity : 0.8205
#          Pos Pred Value : 0.7407
#          Neg Pred Value : 0.6275
#              Prevalence : 0.5000
#          Detection Rate : 0.2564
#    Detection Prevalence : 0.3462
#       Balanced Accuracy : 0.6667


I bet we can do better.

A natural approach is to use a CART (decision tree) model, which (when there is only one variable) simply finds the optimal split. In R, you can do that with ?ctree from the party package.

library(party)

cart.model = ctree(ind~values, dat)
windows()
plot(cart.model)


You can see that the model will call a value "condition1" if it is $$\le5.7$$, and "condition2" otherwise (note that the median of condition1 is $$3.9$$). Here is the confusion matrix:

confusionMatrix(predict(cart.model), dat$ind) # Confusion Matrix and Statistics # # Reference # Prediction cond1 cond2 # cond1 39 15 # cond2 0 24 # # Accuracy : 0.8077 # ... # # Sensitivity : 1.0000 # Specificity : 0.6154 # Pos Pred Value : 0.7222 # Neg Pred Value : 1.0000 # Prevalence : 0.5000 # Detection Rate : 0.5000 # Detection Prevalence : 0.6923 # Balanced Accuracy : 0.8077  This rule yields an accuracy of $$0.8077$$, instead of $$0.6667$$. From the plot and the confusion matrix, you can see that true condition1 members are never misclassified as condition2. This falls out of optimizing the accuracy of the rule and the assumption that both types of misclassification are equally bad; you can tweak the model fitting process if that isn't true. On the other hand, I would be remiss if I didn't point out that a classifier necessarily throws away a lot of information and is typically suboptimal (unless you really need classifications). You may want to model the data so that you can get the probability a value will be a member of condition2. Logistic regression is the natural choice here. Note that because your condition2 is much more spread out than condition1, I added a squared term to allow for a curvilinear fit: lr.model = glm(ind~values+I(values^2), dat, family="binomial") lr.preds = predict(lr.model, type="response") ord = order(dat$values)
dat      = dat[ord,]
lr.preds = lr.preds[ord]

windows()
with(dat, plot(values, ifelse(ind=="cond2",1,0),
ylab="predicted probability of condition2"))
lines(dat$values, lr.preds)  This is clearly giving you more, and better, information. It is not recommended that you throw away the extra information in your predicted probabilities and dichotomize them into classifications, but for the sake of comparison with the rules above, I can show you the confusion matrix that comes from doing so with your logistic regression model: lr.class = ifelse(lr.preds<.5, "cond1", "cond2") confusionMatrix(lr.class, dat$ind)
# Confusion Matrix and Statistics
#
#           Reference
# Prediction cond1 cond2
#     cond1    36     8
#     cond2     3    31
#
#                Accuracy : 0.859
# ...
#
#             Sensitivity : 0.9231
#             Specificity : 0.7949
#          Pos Pred Value : 0.8182
#          Neg Pred Value : 0.9118
#              Prevalence : 0.5000
#          Detection Rate : 0.4615
#    Detection Prevalence : 0.5641
#       Balanced Accuracy : 0.8590


The accuracy is now $$0.859$$, instead of $$0.8077$$.

• @gung That is great response, I just not understand the last probability graph i.e "predicted probability of condition2". Can you please tell me about it – Umar Nov 14 '15 at 14:26
• @Umar, it's just a plot of your data & the predictions from the logistic regression model. If you're not familiar w/ LR, it finds the predicted probability that the response is condition2 for each possible input value. You can read more about LR in the threads tagged under logistic; some of my answers that might help you would be 1, 2, & 3. – gung Nov 15 '15 at 16:51
• Comments are not for extended discussion; this conversation has been moved to chat. – gung May 29 at 13:01

Here is one of many possibilities. Back in 1979, Emanuel Parzen suggested hybridising the quantile plot and the box plot. Some references are given below. Clearly, the box of the box plot shows median and quartiles, which are just key quantiles. Showing all of the data, namely all the quantiles or order statistics, is entirely possible, at least with a small number of groups (as in this thread) and a small or moderate number of observations (as in this thread too). In fact the design extends quite well to larger sample sizes. Outliers, granularity, ties, grouping and gaps (whichever way you want to think about such features) are always evident as well as general level, spread and shape. The graph is not subject to artefacts or side-effects of arbitrary rules of thumb such as what is or is not within 1.5 IQR of the nearer quartile. Conversely, it may offer too much detail for some tastes, but faced with a less than ideal graph one just moves on.

It is reasonable to point out that quantile plots are just cumulative distribution plots with axes reversed, although they are more often shown as point patterns than as connected lines.

Cox (2012) reported one Stata implementation and his stripplot (Stata users can download from SSC) offers another. Implementation should be trivial in any major statistical or mathematical software.

I think this kind of display offers much more detail than a conventional box plot, which here does not fully exploit the space available. A conventional box plot can be helpful for 10-100 groups or variables, where some severe reduction of the data may be needed, but it throws out possibly interesting fine structure for the common few-group or few-variable case.

Another key virtue of this graph is that it echoes the elementary but fundamental fact that just as half the values are inside the box, so also half the values are outside the box (and often the most interesting or more important half). I've seen even experienced statistical people misled by the stark contrast between fat box and thin whiskers. The classic illustration of this is any U-shaped distribution or any distribution with two big clumps of approximately equal size. The box will then be long and fat and the whiskers short and thin. People often miss the fact that such whiskers are hiding the highest densities. Tukey (1977) gave an example of this with Rayleigh's data.

In this case and in many others logarithmic scale is used. In principle, the quantile-box plot is easily compatible with any monotonic transformation, as the transform of the quantiles is identical to the quantiles of the transformed values. (There is some small print qualifying that, arising because median and quartiles may be be produced by averaging of adjacent order statistics, which doesn't usually bite.)

I don't offer herewith any kind of graphical substitute for a significance test. This is an exploratory device.

Cox, N.J. 2012. Axis practice, or what goes where on a graph. Stata Journal 12(3): 549-561. .pdf accessible here

Parzen, E. 1979a. Nonparametric statistical data modeling. Journal, American Statistical Association 74: 105-121.

Parzen, E. 1979b. A density-quantile function perspective on robust estimation. In Launer, R.L. and G.N. Wilkinson (Eds) Robustness in statistics. New York: Academic Press, 237-258.

Parzen, E. 1982. Data modeling using quantile and density-quantile functions. In Tiago de Oliveira, J. and Epstein, B. (Eds) Some recent advances in statistics. London: Academic Press, 23-52.

Tukey, J.W. Exploratory Data Analysis. Reading, MA: Addison-Wesley.

• can we reproduce the analysis (i.e., the plot) that you created? (can you include the code if you have plotted in R or similar software) – Umar Nov 29 '15 at 9:45
• The plot was produced with stripplot in Stata. I don't know if you consider that "similar to" R. @Glen_b evidently used R for the same kind of plot in his answer to stats.stackexchange.com/questions/114744/… – Nick Cox Nov 29 '15 at 10:37