%
% function stats = rm_anova2(Y,S,F1,F2,FACTNAMES)
%
% Twofactor, withinsubject repeated measures ANOVA.
% For designs with two withinsubject factors.
%
% Parameters:
% Y dependent variable (numeric) in a column vector
% S grouping variable for SUBJECT
% F1 grouping variable for factor #1
% F2 grouping variable for factor #2
% FACTNAMES a cell array w/ two char arrays: {'factor1', 'factor2'}
%
% Y should be a 1d column vector with all of your data (numeric).
% The grouping variables should also be 1d numeric, each with same
% length as Y. Each entry in each of the grouping vectors indicates the
% level # (or subject #) of the corresponding entry in Y.
%
% Returns:
% stats is a cell array with the usual ANOVA table:
% Source / ss / df / ms / F / p
%
% Notes:
% Program does not do any input validation, so it is up to you to make
% sure that you have passed in the parameters in the correct form:
%
% Y, S, F1, and F2 must be numeric vectors all of the same length.
%
% There must be at least one value in Y for each possible combination
% of S, F1, and F2 (i.e. there must be at least one measurement per
% subject per condition).
%
% If there is more than one measurement per subject X condition, then
% the program will take the mean of those measurements.
%
% Aaron Schurger (2005.02.04)
% Derived from Keppel & Wickens (2004) "Design and Analysis" ch. 18
%
1.4.0.0  Fixed one minor error in the labeling of the output, and also modified the comments. 

1.3.0.0  Fixed a minor error in the code. Uploaded new version. I had fixed this problem quite a while back, and uploaded the file. It may not have uploaded properly the first time. Thanks to Johan Carlin for bringing the problem to my attention. 

1.0.0.0  Reviewer Ted Zanto (zanto@ccs.fau.edu) noticed a minor error on line 133: FACTNAMES{1} should be FACTNAMES{2}. Corrected this error. This error would have been of little or no consequence to users of the program. 

There was a minor problem in the code (line 70) which would produce inaccurate results if you did not average your data within each condition prior to calling the function. This is now fixed. 

An error on line 70 of the code produced errors if you ran the ANOVA on your raw data, without having previously averaged the measurements within each cell. This feature now works correctly. 
Create scripts with code, output, and formatted text in a single executable document.
Konstantinos Tsikonofilos (view profile)
Amberle McKee (view profile)
There seems to be some sort of major flaw in the code. No matter what data I input, I only get nans out. Based on previous comments, it looks like the code used to work, so my guess is that an error was introduced in a patch that results in the data not being indexed appropriately and only nans to come out the other end. I've tried using this function on real and made up data. I've tried modifying how the data was input. I've tried stopping the code and following it at every point through the code. It always ends in nans and as far as I can tell, it seems to be an indexing issue. Hopefully this issue is resolved soon. This is exactly the kind of function I need for my data. But until it is fixed, I cannot use it.
Xiuyun Wu (view profile)
Danlei Chen (view profile)
Ross Wilkinson (view profile)
Here are the edits I made to include generalized eta squared into the script (starting at line 136):
n2gA = ssA / (ssA + ssS + ssAS + ssBS + ssABS);
n2gB = ssB / (ssB + ssS + ssAS + ssBS + ssABS);
n2gAB = ssAB / (ssAB + ssS + ssAS + ssBS + ssABS);
% return values
stats = {'Source','SS','df','MS','F','p','n2g';...
FACTNAMES{1}, ssA, dfA, msA, fA, pA, n2gA;...
FACTNAMES{2}, ssB, dfB, msB, fB, pB, n2gB;...
[FACTNAMES{1} ' x ' FACTNAMES{2}], ssAB, dfAB, msAB, fAB, pAB, n2gAB;...
[FACTNAMES{1} ' x Subj'], ssAS, dfAS, msAS, [], [], [];...
[FACTNAMES{2} ' x Subj'], ssBS, dfBS, msBS, [], [], [];...
[FACTNAMES{1} ' x ' FACTNAMES{2} ' x Subj'], ssABS, dfABS, msABS, [], [], [];...
'Subjects', ssS, dfS, msS, [], [], []};
return
Arsene Ella (view profile)
Hi Aaron
I've got NaN output for example data of the matlab anova2.....
load popcorn
popcorn (Y = Data)
5.5000 4.5000 3.5000
5.5000 4.5000 4.0000
6.0000 4.0000 3.0000
6.5000 5.0000 4.0000
7.0000 5.5000 5.0000
7.0000 5.0000 4.5000
This example is could be designed like this with your code:
S (Subjects or Different measures)
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
F1 (Brand Factor (Gourmet =1, National =2, Genneric = 3) )
1 2 3
1 2 3
1 2 3
1 2 3
1 2 3
1 2 3
F2 (Popper factor (OIL=1, AIR=2) )
1 1 1
1 1 1
1 1 1
2 2 2
2 2 2
2 2 2
Setting everything in 1d column vectors
Y S F1 F2
5.5 1 1 1
5.5 2 1 1
6.0 3 1 1
6.5 4 1 2
7.0 5 1 2
7.0 6 1 2
4.5 1 2 1
4.5 2 2 1
4.0 3 2 1
5.0 4 2 2
5.5 5 2 2
5.0 6 2 2
3.5 1 3 1
4.0 2 3 1
3.0 3 3 1
4.0 4 3 2
5.0 5 3 2
4.5 6 3 2
Setting the FACTNAMES cell array:
BRAND = {'Gour', 'Nati', 'Gene'}
POPPER = {'Oil', 'Air'}
FACTNAMES = {BRAND, POPPER}
Launching the program:
stats = rm_anova2(Y,S,F1,F2,FACTNAMES)
I've got this result:
stats =
'Source' 'SS' 'df' 'MS' 'F' 'p'
{1x3 cell} [NaN] [ 2] [NaN] [NaN] [NaN]
{1x2 cell} [NaN] [ 1] [NaN] [NaN] [NaN]
{1x6 cell} [NaN] [ 2] [NaN] [NaN] [NaN]
{1x4 cell} [NaN] [10] [NaN] [] []
{1x3 cell} [NaN] [ 5] [NaN] [] []
{1x7 cell} [NaN] [10] [NaN] [] []
Why???
Marta Bienkiewicz (view profile)
I get NaN output for perfectly ok data....
Silvia Marchesotti (view profile)
It's a super useful and great piece of code!
A big thanks to Aaron Schurger!
64426 (view profile)
Hi all, I have recently used this code to run rmANOVA. It is great. I have a question regarding the writing up the result. Since the code only gives Source / ss / df / ms / F / p values I am not sure how to report this. Is there an updated version which also includes the error?
Here is what I got:
'Source' 'SS' 'df' 'MS' 'F' 'p'
'Factor1' [ 2.4939] [ 2] [ 1.2469] [16.8086] [5.8960e06]
'Factor2' [305.1127] [ 9] [33.9014] [59.9041] [ 0]
'Factor1 x Factor2' [ 15.7699] [ 18] [ 0.8761] [11.9694] [ 0]
'Factor1 x Subj' [ 2.8190] [ 38] [ 0.0742] [] []
'Factor2 x Subj' [ 96.7737] [171] [ 0.5659] [] []
'Factor1 x Factor2 x Subj' [ 25.0327] [342] [ 0.0732] [] []
Is there any way to get the error calculated also to get "[] or [0]" as a value?
I will appreciate your help!
Thanks in advance.
Yueqi Ren (view profile)
What does the other pvalues (corresponding to FACTNAMES{1} and to FACTNAMES{2}, respectively) mean? I'm don't quite follow the procedure you use to find those pvalues. Any clarification is appreciated!
Dish (view profile)
Aaron, how do we estimate the effect size here. Usually eta2 is used for effect size = SSeffect / SStotal.
In case of an example that I ran with repeated measures, 2 factors each with 2 levels and 1 response variable, I got the 'source' in the table as:
factor 1, factor 2, factor 1 x factor 2, factor 1 x subjects , factor 2 x subjects, factor 1 x factor 2 x subjects. I am not sure if the SStotal the sum of all of these..? Can you please confirm.
Echo M (view profile)
Thank you for the script, Aaron. will this script work for unbalanced samples (i.e. different number of subjects
per group) ?
K Jay (view profile)
Can we include betweensubject factors here?
Antonietta Gabriella Liuzzi (view profile)
Hi all,
It's not clear to me how input data (Y, S, F1,F2, FACTNAMES) have to be arranged. Can someone gives an example? Thanks!
Timothy Myers (view profile)
I am not sure what to put for the FACTNAMES. I have entered "1"s and "2"s for the conditions in F1 & F2 is this correct?
Lisa (view profile)
Solved it!
Chloe (view profile)
Is the result of pvalue from first line indicating the result of within subject?
Aaron Schurger (view profile)
Hi, Marc,
This procedure is strictly for situations where you have exactly two withinsubjects factors. To my knowledge there exists no nfactor repeated measures ANOVA algorithm. Just going from twofactor to threefactor you have a huge jump in complexity of the algorithm, and when you have different numbers of betweensubjects and withinsubjects factors things get really scary really fast. But there are functions on the File Exchange for more than two factors.
Marc (view profile)
Will this file work for a multifactor (more than two factors) ANOVA?
Will it also work on a OneWay ANOVA?
Jordan (view profile)
This seems very promising, but I can't figure out what kind of input is needed. For instance, what is d in the function definitions, and are Y and grouping vectors meant to comprise one column or multiple columns? It would be very helpful if the author could include with his download a small .mat file with sample inputs for Y, F1, F2 etc.
Marieke (view profile)
the script works now  I appear to have had an old version of the script.
Erin (view profile)
Good submission. I found this script gives the same results as anovan. To do repeated measures with anovan, its necessary to make another factor for subjects, and specify that factor as 'random'.
Marieke Rohde (view profile)
for the data that made me spot the bug the script displays the following first three lines of the ANOVA tables.
If you take the average from multiple cells by hand:
'Source'SS df MS F p
'cond' 1.0413 1 1.0413 1.8483 0.1971
'hand' 0.2325 1 0.2325 1.7135 0.2132
'cxh' 0.1184 1 0.1184 2.7210 0.1230
if you enter several values for multiple cells, according to documentation, it should do the same thing automatically, but doesn't:
Source SS df MS F p
'cond' 1.0413 1 1.0413 1.8483 0.1971
'hand' 0.2325 1 0.2325 1.7135 0.2132
cdxhd 0.1184 1 0.1184 1.4417e05 0.9970
which is jsut plainly wrong (note that first 3 columns are identical). i would be surprised if Statistica did the same. i did the calculations by hand at the time to figure out what exactly went wrong but cannot remember  if you're interested in the data please be in touch.
titou (view profile)
Thanks a lot.
I precise I just needed to change :
F1==F1_lvls(i)
in
strcmp(F1,F1_lvls(i))==1
and it works great ! (same results as Statistica)
Jamie (view profile)
I agree this is a very well written script. However, I am somewhat confused about the Y input variable. In the comments above it says that 'Y' should be a column vector (I assume this means (:, 1)). My confusion comes from the following lines:
for i=1:a % F1
for j=1:b % F2
for k=1:n % Subjs
INDS{i,j,k} = ...
CELLS{i,j,k} = Y(INDS{i,j,k});
MEANS(i,j,k) = mean(CELLS{i,j,k});
end
end
end
The '...' was placed instead of the code to create the indices. The line CELLS{i,j,k} = Y(INDS{i,j,k}); generates a 3D cell from Y, which makes sense to have the data in three dimensions, however Y is a 1D column and creates a large number of NaNs.
Also, Matlab produces the following error:
??? Error using ==> horzcat
CAT arguments dimensions are not consistent.
Error in ==> rm_anova2 at 138
stats = {'Source','SS','df','MS','F','p';...
Long story short, what am I not getting about this?
Marieke Rohde (view profile)
There's a mistake in this script: if several measurements are provided for one cell, it gives wrong values for the interaction. help says it would take the average in that case, which it does for the most part, but at some point it gets confused with the number of measurements taken and F and p are then really wrong (only concerns interaction with several values per cell).
By the way, RMAOV2 > same functionality, even though a bit bulky, takes the variance across repeated measurements for the same cell into consideration.
Alberich Qi (view profile)
I think it should be written as :
FACTNAMES = {F1name, F2name};
F1name = {'abc' , ..., 'xyz'};
F2name = {'xx', ..., 'yy'};
It can work well in my script.
Robert (view profile)
I would also appreciate a one line example of how to enter FACTNAMES. I'm getting an error. Thanks!
Negar (view profile)
Hi,
Can someone give me a one line example of how to enter FACTNAMES? I'd appreciate it.
Aaron Schurger (view profile)
Hi, Zachary,
Good question. No, it was not designed to deal with a different number of subjects on each factor. Sorry about that. It might not be too complicated to code, but I imagine that there are some statistical issues to be mindful of, and I would want to look into that before changing the code. In the meantime, you might be able to insert a dummy value, which is just the mean of the other values, just to make the program work. One thing that I can do is to make the program generate an error instead of just giving back nan's. It would help to see the data, just as you passed them to the program. Aaron
Zachary Danziger (view profile)
The stats output is a cell array of NaNs. Is this software capable of dealing with unequally distributed data? I.e., 7 subjects are evaluated on factor 1, but only 6 are evaluated on factor 2.
It would make my day if you could add GreenhouseGeiser correction for violating the sphericity assumption of repeated measures ANVOA.
This worked well for me.
Examples with data are always very helpful.. this is what this lacks
The author had corrected the code after Ted Zanto's comment in 2005.
It is great. Thank you!!!
Excellent program...does exactly what it's designed for. Easy to implement and coded in a very straightforward manner. Results were confirmed in SPSS...right on the mark.
One tiny error on line 133: FACTNAMES{1} should be FACTNAMES{2}...but this merely a labeling issue.
Nonetheless, it's a great program, thanks Aaron!
A very wellwritten program (of course, I wrote it myself). One or two additional features are of interest, so I would not yet call it excellent.