Non-parametric tests
Nonparametric tests
Parametric vs Nonparametric
Attribute | Parametric | Nonparametric |
---|---|---|
distribution | normaly distributed | any distribution |
sampling | random sample | random sample |
sensitivity to outliers | yes | no |
works with | large data sets | small and large data sets |
speed | fast | slow |
Ranking
= c(1, 4, 6, 7, 8, 9)
x = c(1, 4, 6, 7, 8, 39)
y
layout(matrix(1:2, 1, 2))
boxplot(x, horizontal=T, col='red')
boxplot(y, horizontal=T, col='red')
kable(rbind(rx = rank(x), ry = rank(y)))
rx | 1 | 2 | 3 | 4 | 5 | 6 |
ry | 1 | 2 | 3 | 4 | 5 | 6 |
Ties
# Scores
= c(11, 42, 62, 73, 84, 84, 42, 73, 90)
x
# sort
= sort(x)
order
# assign ranks
= 1:length(x)
ranks
# solve for ties
= rank(sort(x)) ties
x | 11 | 42.0 | 62.0 | 73 | 84.0 | 84.0 | 42.0 | 73.0 | 90 |
order | 11 | 42.0 | 42.0 | 62 | 73.0 | 73.0 | 84.0 | 84.0 | 90 |
ranks | 1 | 2.0 | 3.0 | 4 | 5.0 | 6.0 | 7.0 | 8.0 | 9 |
ties | 1 | 2.5 | 2.5 | 4 | 5.5 | 5.5 | 7.5 | 7.5 | 9 |
\[\frac{2 + 3}{2} = 2.5, \frac{5 + 6}{2} = 5.5, \frac{7 + 8}{2} = 7.5\]
Procedure
- Assumption: independent random samples.
- Hypothesis:
\(H_0\) : equal population distributions (implies equal mean ranking)
\(H_A\) : unequal mean ranking (two sided)
\(H_A\) : higher mean ranking for one group. - Test statistic is difference between mean or sum of ranking.
- Standardise test statistic
- Calculate P-value one or two sided.
- Conclude to reject \(H_0\) if \(p < \alpha\).
Wilcoxon rank-sum test
Independent 2 samples
Wilcoxon rank-sum test
Developed by Frank Wilcoxon the rank-sum test is a nonparametric alternative to the independent samples t-test.
By first ranking \(x\) and then sum these ranks per group one would expect, under the null hypothesis, equal values for both groups.
After standardising this difference one can test using a standard normal distribution.
Sum the ranks
Simulate data
= 20
n = rep(c("Ecstasy","Alcohol"),each=n/2)
factor = ifelse(factor == "Ecstacy", 0, 1)
dummy .0 = 23
b.1 = 5
b= rnorm(n, 0, 1.7)
error = b.0 + b.1*dummy + error
depres = round(depres)
depres
<- data.frame(factor, depres)
data
## add the ranks
$R <- rank(data$depres) data
Example
Calculate the sum of ranks per group
<- aggregate(R ~ factor, data, sum)
R R
factor R
1 Alcohol 101
2 Ecstasy 109
So W is the lowest
\[W=min\left(\sum{R_1},\sum{R_2}\right)\]
<- min(R$R)
W W
[1] 101
Standardise W
To calculate the Z score we need to standardise the W. To do so we need the mean W and the standard error of W.
For this we need the sample sizes for each group.
<- aggregate(R ~ factor, data, length)
n
.1 = n$R[1]
n.2 = n$R[2]
n
cbind(n.1, n.2)
n.1 n.2
[1,] 10 10
Mean W
\[\bar{W}_s=\frac{n_1(n_1+n_2+1)}{2}\]
= (n.1*(n.1+n.2+1))/2
W.mean W.mean
[1] 105
SE W
\[{SE}_{\bar{W}_s}=\sqrt{ \frac{n_1 n_2 (n_1+n_2+1)}{12} }\]
= sqrt((n.1*n.2*(n.1+n.2+1))/12)
W.se W.se
[1] 13.22876
Calculate Z
\[z = \frac{W - \bar{W}}{{SE}_W}\]
Which looks a lot like
\[\frac{X - \bar{X}}{{SE}_X} \text{or} \frac{b - \mu_{b}}{{SE}_b} \]
= (W - W.mean) / W.se
z z
[1] -0.3023716
Test for significance 1 sided
if(!"visualize" %in% installed.packages()){ install.packages("visualize") }
library("visualize")
visualize.norm(z, section="lower")
Test for significance 2 sided
visualize.norm(c(z,-z), section="tails")
Effect size
\[r = \frac{z}{\sqrt{N}}\]
= sum(n$R)
N = z / sqrt(N)
r r
[1] -0.06761234
Mann–Whitney test
\[U = n_1 n_2 + \frac{n_1 (n_1 + 1)}{2} - R_1\]
= (n.1*n.2)+(n.1*(n.1+1))/2-R$R[1]
U U
[1] 54
\(\bar{U}\) and \({SE}_U\) for non tied ranks
\[\bar{U} = \frac{n_1 n_2}{2}\]
.1*n.2)/2 (n
[1] 50
\[{SE}_U = \sqrt{\frac{n_1 n_2 (n_1 + n_2 + 1)}{12}}\]
sqrt((n.1*n.2*(n.1+n.2+1))/12)
[1] 13.22876
Wilcoxon signed-rank test
Paired 2 samples
Wilcoxon signed-rank test
The Wilcoxon signed-rank test is a nonparametric alternative to the paired samples t-test. It assigns + or - signs to the difference between two repeated measures. By ranking the differences and summing these ranks for the positive group, the null hypothesis is tested that both positive and negative differences are equal.
Simulate data
= 20
n = rep(c("Ecstasy","Alcohol"),each=n/2)
factor = ifelse(factor == "Ecstacy", 0, 1)
dummy .0 = 23
b.1 = 5
b= rnorm(n, 0, 1.7)
error = b.0 + b.1*dummy + error
depres = round(depres)
depres
<- data.frame(factor, depres)
data
<- subset(data, factor=="Ecstasy")$depres
Ecstasy <- subset(data, factor=="Alcohol")$depres
Alcohol
<- data.frame(Ecstasy, Alcohol) data
Example
Calculate T
# Calculate difference in scores between first and second measure
$difference = data$Ecstasy - data$Alcohol
data
# Calculate absolute difference in scores between first and second measure
$abs.difference = abs(data$Ecstasy - data$Alcohol)
data
# Create rank variable with place holder NA
$rank <- NA
data
# Rank only the difference scores
which(data$difference != 0),'rank'] <- rank(data[which(data$difference != 0),
data['abs.difference'])
# Assign a '+' or a '-' to those values
$sign = sign(data$Ecstasy - data$Alcohol)
data
# Add positive and negative rank to test if else
$rank_pos = with(data, ifelse(sign == 1, rank, 0 ))
data$rank_neg = with(data, ifelse(sign == -1, rank, 0 )) data
The data
Calculate \(T_+\)
# Calculate the sum of the positive ranks
= sum(data$rank_pos)
T_pos T_pos
[1] 18.5
# Calculate N without 0 (no differences).
= sum(abs(data$sign))
n n
[1] 7
Calculate \(\bar{T}\) and \({SE}_{T}\)
\[\bar{T} = \frac{n(n+1)}{4}\]
= (n*(n+1))/4
T_mean T_mean
[1] 14
\[{SE}_{T} = \sqrt{\frac{n(n+1)(2n+1)}{24}}\]
= sqrt( (n*(n+1)*(2*n+1)) / 24 ) SE_T
Calculate Z
\[z = \frac{T_+ - \bar{T}}{{SE}_T}\]
= (T_pos - T_mean)/SE_T
z z
[1] 0.7606388
Test for significance
visualize.norm(c(z,-z), section="tails")
Effect size
\[r = \frac{z}{\sqrt{N}}\]
Here \(N\) is the number of observations.
= 20
N = z / sqrt(N)
r r
[1] 0.170084
Kruskal–Wallis test
Independent >2 samples
Kruskal–Wallis test
Created by William Henry Kruskal (L) and Wilson Allen Wallis (R), the Kruskal-Wallis test is a nonparametric alternative to the independent one-way ANOVA.
The Kruskal-Wallis test essentially subtracts the expected mean ranking from the calculated oberved mean ranking, which is \(\chi^2\) distributed.
Simulate data
= 30
n = rep(c("ecstasy","alcohol","control"), each=n/3)
factor
.1 = ifelse(factor == "alcohol", 1, 0)
dummy.2 = ifelse(factor == "ecstasy", 1, 0)
dummy.0 = 23
b.1 = 0
b.2 = 0
b= rnorm(n, 0, 1.7)
error
# Model
= b.0 + b.1*dummy.1 + b.2*dummy.2 + error
depres = round(depres)
depres
<- data.frame(factor, depres) data
Assign ranks
# Assign ranks
$ranks = rank(data$depres) data
The data
Calculate H
\[H = \frac{12}{N(N+1)} \sum_{i=1}^k \frac{R_i^2}{n_i} - 3(N+1)\]
- \(N\) total sample size
- \(n_i\) sample size per group
- \(k\) number of groups
- \(R_i\) rank sums per group
Calculate H
# Now we need the sum of the ranks per group.
= aggregate(ranks ~ factor, data = data, sum)$ranks
R.i R.i
[1] 207.0 121.5 136.5
# De total sample size N is:
= nrow(data)
N
# And the sample size per group is n_i:
= aggregate(depres ~ factor, data=data, length)$depres
n.i n.i
[1] 10 10 10
Calculate H
\[H = \frac{12}{N(N+1)} \sum_{i=1}^k \frac{R_i^2}{n_i} - 3(N+1)\]
= ( 12/(N*(N+1)) ) * sum(R.i^2/n.i) - 3*(N+1)
H H
[1] 5.37871
And the degrees of freedom
= 3
k = k - 1 df
Test for significance
visualize.chisq(H, df, section="upper")
Friedman’s ANOVA
Paired >2 samples
Friedman’s ANOVA
Created by William Frederick Friedman the Friedman’s ANOVA is a nonparametric alternative to the repeated one-way ANOVA.
Just like the Kruskal-Wallis test, Friedman’s ANOVA, subtracts the expected mean ranking from the calculated observed mean ranking, which is also \(\chi^2\) distributed.
Simulate data
= 30
n = rep(c("ecstasy","alcohol","control"), each=n/3)
factor
.1 = ifelse(factor == "alcohol", 1, 0)
dummy.2 = ifelse(factor == "ecstasy", 1, 0)
dummy.0 = 23
b.1 = 0
b.2 = 0
b= rnorm(n, 0, 1.7)
error
# Model
= b.0 + b.1*dummy.1 + b.2*dummy.2 + error
depres = round(depres)
depres
<- data.frame(factor, depres) data
Simulate data
<- subset(data, factor=="ecstasy")$depres
ecstasy <- subset(data, factor=="alcohol")$depres
alcohol <- subset(data, factor=="control")$depres
control
<- data.frame(ecstasy, alcohol, control) data
The data
Assign ranks
Rank each row.
# Rank for each person
= t(apply(data, 1, rank)) ranks
The data with ranks
Calculate \(F_r\)
\[F_r = \left[ \frac{12}{Nk(k+1)} \sum_{i=1}^k R_i^2 \right] - 3N(k+1)\]
- \(N\) total number of subjects
- \(k\) number of groups
- \(R_i\) rank sums for each group
Calculate \(F_r\)
Calculate ranks sum per condition and \(N\).
= apply(ranks, 2, sum)
R.i R.i
ecstasy alcohol control
20.0 19.5 20.5
# N is number of participants
= 10 N
Calculate \(F_r\)
\[F_r = \left[ \frac{12}{Nk(k+1)} \sum_{i=1}^k R_i^2 \right] - 3N(k+1)\]
= 3
k = ( ( 12/(N*k*(k+1)) ) * sum(R.i^2) ) - ( 3*N*(k+1) )
F.r F.r
[1] 0.05
And the degrees of freedom
= k - 1 df
Test for significance
visualize.chisq(F.r, df, section="upper")