function Bowkertest(X,t,alpha)
%BOWKERTEST Bowker's Test for Symmetry.
% BOWKERTEST, performs the Bowker's test for symmetry. It is an
% extension of the McNemar test to a KxK situation. There are
% now K response categories for the two dependent samples.
% The null hypothesis is that the probabilities in the square
% table satisfy symmetry or that there is no sifnificant shift
% from one response category to another from sample 1 to
% sample 2.
%
% So, according to the next KxK table design,
%
% Dependent sample 1
% ----------------------------
% 1 2 . . . K
% ----------------------------
% 1 n_11 n_12 . . . n_1K n_1+
%
% 2 n_21 n_22 . . . n_2K n_2+
% . . . .
% Dependent sample 2 . . n_ij . n_i+
% . . . . . . .
%
% K n_K1 n_K2 . . . n_KK n_K+
% ----------------------------
% n_+1 n_+2 n_+j n_+K n
%
% One test statistic of symmetry for two dependent samples with K
% nominal classifications is the usual Pearson statistic with the
% expected counts (E_ij) being the mean of the corresponding diagonal
% cell counts,
%
% B = K_SUM_i=1 K_SUM_j=1 (O_ij - E_ij)^2/E_ij =
%
% K_SUM_i=1 K_SUM_j=1 (n_ij - (n_ij + n_ji)/2)^2/(n_ij + n_ji)/2 =
%
% K-1_SUM_i=1 K_SUM_j=i+1 (n_ij - n_ji)^2/(n_ij + n_ji); i < j
%
% Where, i,j = 1,2,...,K. The diagonal cells in the table do not
% contribute any information to the test.
%
% When the null hypothesis of symmetry is true,
%
% Ho: p_ij = p_ji, for all pairs of table cells,
%
% then B will have a Chi-square distribution with K(K-1) degrees of
% freedom. This is the basis of the proposed test by Bowker (1948).
% If K = 2, then B simplifies to the McNemar test statistic.
%
% Syntax: function Bowkertest(X,t,alpha)
%
% Inputs:
% X - data matrix defined by the KxK observed frequency cells.
% t - desired test [t = 1, one-tail; t = 2, two-tail (default)].
% alpha - significance level (default = 0.05).
%
% Output:
% A table with the proportion of success for the dependent samples
% and the P-values using and not correction for discontinuity.
%
% Example: From the example given on pages 15-16 from the Biostatistics-I
% course (Fall 2002) and available on the internet webpage
% (http://www.utstat.toronto.edu/georget/CHL5201./Lecture8/Cortinslide.doc).
% Medical researchers are interested in evaluating the efficacy of a new
% treatment for a skin condition. Dermatologists from participating
% clinics were trained to conduct the study and to evaluate the condition.
% After the training, two dermatologists examined patients with the skin
% condition from a pilot study and rated the same patients. The possible
% evaluations are terrible, poor, marginal, and clear. Each count in the
% table represents a single patient. For example, 4 patients were rated
% 'terrible' by dermatologist 1 and 'poor' by dermatologist 2. Bowker's
% test ask if there is evidence that one of the two dermatologists is
% systematically downrating the patients, relative to the other dermatologist.
% We re-classify the categories as 1=terrible, 2=poor, 3=marginal, 4=clear.
%
% Dermatologist 2
% ---------------------------------------
% 1 2 3 4
% ---------------------------------------
% 1 10 4 1 0
%
% 2 5 10 12 2
% Dermatologist 1
% 3 2 4 12 5
%
% 4 0 2 6 13
% ---------------------------------------
%
% Data matrix must be:
% X=[10 4 1 0;5 10 12 2;2 4 12 5;0 2 6 13];
%
% Calling on Matlab the function:
% Bowkertest(X,2,0.05)
%
% Answer is:
%
% Table for the Bowker's test for symmetry.
% ------------------------------------------------------------------
% B statistic Number of categories df P
% ------------------------------------------------------------------
% 4.5354 4 6 0.6046
% ------------------------------------------------------------------
% For a selected two-saided test.
% With a given significance of: 0.050
% [If P-value >= alpha, test is not significative. Else, it results significative.]
%
% Created by A. Trujillo-Ortiz, R. Hernandez-Walls and A. Castro-Perez
% Facultad de Ciencias Marinas
% Universidad Autonoma de Baja California
% Apdo. Postal 453
% Ensenada, Baja California
% Mexico.
% atrujo@uabc.mx
% Copyright (C) November 7, 2004.
%
% To cite this file, this would be an appropriate format:
% Trujillo-Ortiz, A., R. Hernandez-Walls and A. Castro-Perez. (2004). Bowkertest:
% Bowker's Test for Symmetry. A MATLAB file. [WWW document]. URL http://
% www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=6322
%
% References:
%
% Agresti, A. (2002), Categorical Data Analysis (2nd ed.). NY: John Wiley & Sons.
% Bowker, A.H. (1948), Bowker's Test for Symmetry. Journal of the American
% Statistical Association, 43:572-574.
%
if nargin < 3,
alpha = 0.05; %(default)
elseif (length(alpha)>1),
error('Requires a scalar alpha value.');
elseif ((alpha <= 0) | (alpha >= 1)),
error('Requires 0 < alpha < 1.');
end;
if nargin < 2,
t = 2; %two-tailed test (default)
end;
[r c] = size(X);
if r ~= c;
error('WARNING:Dimension of the input data matrix must be the same.');
return;
end;
M = X-diag(diag(X));
L = tril(M);
U = triu(M)';
D = ((L-U).^2)./(L+U); %calculation of the K(K-1)/2 values to sum
D = D(~isnan(D)); %only keept valid values: NaNs have been removed.
B = sum(D); %Bowker's statistic
v = r*(c-1)/2; %degrees of freedom
%P-value approximation by an asymptotic Chi-square distribution
P = 1-chi2cdf(B,v);
if t == 1;
P = P/2;
else t == 2;
P = P;
end;
disp(' ')
disp('Table for the Bowker''s test for symmetry.')
fprintf('------------------------------------------------------------------\n');
disp(' B statistic Number of categories df P ');
fprintf('------------------------------------------------------------------\n');
fprintf(' %10.4f %10.i %10.i %10.4f\n',[B,r,v,P].');
fprintf('------------------------------------------------------------------\n');
if t == 1;
disp('For a selected one-saided test.')
fprintf('With a given significance of: %.3f\n', alpha);
disp('[If P-value >= alpha, test is not significative. Else, it results significative.]')
else t == 2;
disp('For a selected two-saided test.')
fprintf('With a given significance of: %.3f\n', alpha);
disp('[If P-value >= alpha, test is not significative. Else, it results significative.]')
end;
disp(' ')
return;