-
Notifications
You must be signed in to change notification settings - Fork 14
/
anova_rm.m
207 lines (183 loc) · 5.02 KB
/
anova_rm.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
function [p, table] = anova_rm(X, displayopt)
% [p, table] = anova_rm(X, displayopt)
% Single factor, repeated measures ANOVA.
%
% [p, table] = anova_rm(X, displayopt) performs a repeated measures ANOVA
% for comparing the means of two or more columns (time) in one or more
% samples(groups). Unbalanced samples (i.e. different number of subjects
% per group) is supported though the number of columns (followups)should
% be the same.
%
% DISPLAYOPT can be 'on' (the default) to display the ANOVA table, or
% 'off' to skip the display. For a design with only one group and two or
% more follow-ups, X should be a matrix with one row for each subject.
% In a design with multiple groups, X should be a cell array of matrixes.
%
% Example: Gait-Cycle-times of a group of 7 PD patients have been
% measured 3 times, in one baseline and two follow-ups:
%
% patients = [
% 1.1015 1.0675 1.1264
% 0.9850 1.0061 1.0230
% 1.2253 1.2021 1.1248
% 1.0231 1.0573 1.0529
% 1.0612 1.0055 1.0600
% 1.0389 1.0219 1.0793
% 1.0869 1.1619 1.0827 ];
%
% more over, a group of 8 controls has been measured in the same protocol:
%
% controls = [
% 0.9646 0.9821 0.9709
% 0.9768 0.9735 0.9576
% 1.0140 0.9689 0.9328
% 0.9391 0.9532 0.9237
% 1.0207 1.0306 0.9482
% 0.9684 0.9398 0.9501
% 1.0692 1.0601 1.0766
% 1.0187 1.0534 1.0802 ];
%
% We are interested to see if the performance of the patients for the
% followups were the same or not:
%
% p = anova_rm(patients);
%
% By considering the both groups, we can also check to see if the
% follow-ups were significantly different and also check two see that the
% two groups had a different performance:
%
% p = anova_rm({patients controls});
%
%
% ref: Statistical Methods for the Analysis of Repeated Measurements,
% C. S. Daivs, Springer, 2002
%
% Copyright 2008, Arash Salarian
% mailto://[email protected]
%
if nargin < 2
displayopt = 'on';
end
if ~iscell(X)
X = {X};
end
%number of groups
s = size(X,2);
%subjects per group
n_h = zeros(s, 1);
for h=1:s
n_h(h) = size(X{h}, 1);
end
n = sum(n_h);
%number of follow-ups
t = size(X{1},2);
% overall mean
y = 0;
for h=1:s
y = y + sum(sum(X{h}));
end
y = y / (n * t);
% allocate means
y_h = zeros(s,1);
y_j = zeros(t,1);
y_hj = zeros(s,t);
y_hi = cell(s,1);
for h=1:s
y_hi{h} = zeros(n_h(h),1);
end
% group means
for h=1:s
y_h(h) = sum(sum(X{h})) / (n_h(h) * t);
end
% follow-up means
for j=1:t
y_j(j) = 0;
for h=1:s
y_j(j) = y_j(j) + sum(X{h}(:,j));
end
y_j(j) = y_j(j) / n;
end
% group h and time j mean
for h=1:s
for j=1:t
y_hj(h,j) = sum(X{h}(:,j) / n_h(h));
end
end
% subject i'th of group h mean
for h=1:s
for i=1:n_h(h)
y_hi{h}(i) = sum(X{h}(i,:)) / t;
end
end
% calculate the sum of squares
ssG = 0;
ssSG = 0;
ssT = 0;
ssGT = 0;
ssR = 0;
for h=1:s
for i=1:n_h(h)
for j=1:t
ssG = ssG + (y_h(h) - y)^2;
ssSG = ssSG + (y_hi{h}(i) - y_h(h))^2;
ssT = ssT + (y_j(j) - y)^2;
ssGT = ssGT + (y_hj(h,j) - y_h(h) - y_j(j) + y)^2;
ssR = ssR + (X{h}(i,j) - y_hj(h,j) - y_hi{h}(i) + y_h(h))^2;
end
end
end
% calculate means
if s > 1
msG = ssG / (s-1);
msGT = ssGT / ((s-1)*(t-1));
end
msSG = ssSG / (n-s);
msT = ssT / (t-1);
msR = ssR / ((n-s)*(t-1));
% calculate the F-statistics
if s > 1
FG = msG / msSG;
FGT = msGT / msR;
end
FT = msT / msR;
FSG = msSG / msR;
% single or multiple sample designs?
if s > 1
% case for multiple samples
pG = 1 - fcdf(FG, s-1, n-s);
pT = 1 - fcdf(FT, t-1, (n-s)*(t-1));
pGT = 1 - fcdf(FGT, (s-1)*(t-1), (n-s)*(t-1));
pSG = 1 - fcdf(FSG, n-s, (n-s)*(t-1));
p = [pT, pG, pSG, pGT];
table = { 'Source' 'SS' 'df' 'MS' 'F' 'Prob>F'
'Time' ssT t-1 msT FT pT
'Group' ssG s-1 msG FG pG
'Ineratcion' ssGT (s-1)*(t-1) msGT FGT pGT
'Subjects (matching)' ssSG n-s msSG FSG pSG
'Error' ssR (n-s)*(t-1) msR [] []
'Total' [] [] [] [] []
};
table{end, 2} = sum([table{2:end-1,2}]);
table{end, 3} = sum([table{2:end-1,3}]);
if (isequal(displayopt, 'on'))
digits = [-1 -1 0 -1 2 4];
statdisptable(table, 'multi-sample repeated measures ANOVA', 'ANOVA Table', '', digits);
end
else
% case for only one sample
pT = 1 - fcdf(FT, t-1, (n-s)*(t-1));
pSG = 1 - fcdf(FSG, n-s, (n-s)*(t-1));
p = [pT, pSG];
table = { 'Source' 'SS' 'df' 'MS' 'F' 'Prob>F'
'Time' ssT t-1 msT FT pT
'Subjects (matching)' ssSG n-s msSG FSG pSG
'Error' ssR (n-s)*(t-1) msR [] []
'Total' [] [] [] [] []
};
table{end, 2} = sum([table{2:end-1,2}]);
table{end, 3} = sum([table{2:end-1,3}]);
if (isequal(displayopt, 'on'))
digits = [-1 -1 0 -1 2 4];
statdisptable(table, 'repeated measures ANOVA', 'ANOVA Table', '', digits);
end
end