# An issue with computing the Wilcoxon test using R

I have two independet groups with many sub-groups (illustrated in the code below). I would like to calculate the Wilcoxon test for the two groups. To do that, I have written the following script in R:

g1  <- c(99, 131, 118, 112, 128)
g2  <- c(134, 103, 127, 121, 139)
g3  <- c(110, 123, 100, 131, 108)
g4  <- c(117, 125, 140, 109, 128)
g5  <- c(136, 120, 107, 134, 122)
g6  <- c(114, 101, 128, 110, 141)

df <- data.frame(sg1=c(g1, g2, g3), sg2=c(g4, g5, g6))

result <- wilcox.test(sg1 ~ sg2, data = df)


When I run it, I get the following error:

Error in wilcox.test.formula(sg1 ~ sg2, data = df) :
grouping factor must have exactly 2 levels


• I think you could use wilcox.test(df$sg1, df$sg2). With the formula, it interprets the sg2 as grouping variable. – COOLSerdash Apr 15 at 15:39
• @COOLSerdash I used it and it gave me cannot compute exact p-value with ties – Adam Amin Apr 15 at 15:41
• The Wilcoxon is an ordered ranked test. Basically it will order all of the values from highest to lowest and then calculate the p value based on the order. If two values are equal, then the ordering is not unique and thus it can skew the p values calculation. If the number of ties are small in comparison to the total number of samples, it should not affect the interpretation of the results. – Dave2e Apr 15 at 17:34

I suppose you have two groups, each with 15 observations, that you want to compare:

Method 1:

g1  = c( 99, 131, 118, 112, 128)
g2  = c(134, 103, 127, 121, 139)
g3  = c(110, 123, 100, 131, 108)
g4  = c(117, 125, 140, 109, 128)
g5  = c(136, 120, 107, 134, 122)
g6  = c(114, 101, 128, 110, 141)
sg1 = c(g1, g2, g3); sg2 = c(g4, g5, g6)
wilcox.test(sg1, sg2)

Wilcoxon rank sum test with continuity correction

W = 97, p-value = 0.5335
alternative hypothesis: true location shift is not equal to 0

Warning message:
In wilcox.test.default(sg1, sg2) : cannot compute exact p-value with
ties


Method 2: (Equivalent to Method 1; essentially what is suggested by @COOLserdash.)

x = c(sg1, sg2); gp = rep(1:2, each=15)


wilcox.test(x ~ gp)

     Wilcoxon rank sum test with continuity correction

data:  x by gp
W = 97, p-value = 0.5335
alternative hypothesis: true location shift is not equal to 0

Warning message:
In wilcox.test.default(x = c(99, 131, 118, 112, 128, 134, 103, 127, :
cannot compute exact p-value with ties


As you say, you get a message warning of ties. There are few ties within each group, several between groups. Here is a stripchart of the two samples of size 15.

stripchart(x ~ gp, ylim=c(.5,2.5), meth="stack")


Visually, it is no surprise that the (aproximate) P-value is considerably above 5%.

What follows may be cheating, but it may help to assess the effect of ties. One can 'jitter' the data a bit to break ties, by adding various uniform values in $$(-.2, 2)$$ to the values in x. This will break ties without massively disrupting the rankings. (This illustrates the Comment of @Dave2e.)

jit = runif(30, -.2, .2)
wilcox.test(x+jit ~ gp)

Wilcoxon rank sum test

data:  x + jit by gp
W = 97, p-value = 0.5393
alternative hypothesis: true location shift is not equal to 0


Again the P-value is above $$0.5:$$ nowhere near significant. One more run with different jittering gave about the same P-value. So it seems you are failing to reject because there really is no significant difference. Not because ties are giving a slightly inaccurate P-value.

Furthermore, looking at the original six groups in a stripchart (no jittering), we see no potentially significant differences anywhere. (Generally speaking, it is a good idea to look at data graphically before trying to do tests.)

• Thanks for the brilliant explanation. In this line sg1 = c(g1, g2, g3); sg2 = c(g3, g4, g5) in the first method, should sg2=c(g4,g5,g6)? – Adam Amin Apr 16 at 10:06
• You're right, of course. Errors corrected. P-value somewhat different, but no change in interpretation. – BruceET Apr 16 at 18:09