rm_anova2.m 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. function stats = rm_anova2(Y,S,F1,F2,FACTNAMES)
  2. %
  3. % function stats = rm_anova2(Y,S,F1,F2,FACTNAMES)
  4. %
  5. % Two-factor, within-subject repeated measures ANOVA.
  6. % For designs with two within-subject factors.
  7. %
  8. % Parameters:
  9. % Y dependent variable (numeric) in a column vector
  10. % S grouping variable for SUBJECT
  11. % F1 grouping variable for factor #1
  12. % F2 grouping variable for factor #2
  13. % FACTNAMES a cell array w/ two char arrays: {'factor1', 'factor2'}
  14. %
  15. % Y should be a 1-d column vector with all of your data (numeric).
  16. % The grouping variables should also be 1-d numeric, each with same
  17. % length as Y. Each entry in each of the grouping vectors indicates the
  18. % level # (or subject #) of the corresponding entry in Y.
  19. %
  20. % Returns:
  21. % stats is a cell array with the usual ANOVA table:
  22. % Source / ss / df / ms / F / p
  23. %
  24. % Notes:
  25. % Program does not do any input validation, so it is up to you to make
  26. % sure that you have passed in the parameters in the correct form:
  27. %
  28. % Y, S, F1, and F2 must be numeric vectors all of the same length.
  29. %
  30. % There must be at least one value in Y for each possible combination
  31. % of S, F1, and F2 (i.e. there must be at least one measurement per
  32. % subject per condition).
  33. %
  34. % If there is more than one measurement per subject X condition, then
  35. % the program will take the mean of those measurements.
  36. %
  37. % Aaron Schurger (2005.02.04)
  38. % Derived from Keppel & Wickens (2004) "Design and Analysis" ch. 18
  39. %
  40. %
  41. % Revision history...
  42. %
  43. % 11 December 2009 (Aaron Schurger)
  44. %
  45. % Fixed error under "bracket terms"
  46. % was: expY = sum(Y.^2);
  47. % now: expY = sum(sum(sum(MEANS.^2)));
  48. %
  49. stats = cell(4,5);
  50. F1_lvls = unique(F1);
  51. F2_lvls = unique(F2);
  52. Subjs = unique(S);
  53. a = length(F1_lvls); % # of levels in factor 1
  54. b = length(F2_lvls); % # of levels in factor 2
  55. n = length(Subjs); % # of subjects
  56. INDS = cell(a,b,n); % this will hold arrays of indices
  57. CELLS = cell(a,b,n); % this will hold the data for each subject X condition
  58. MEANS = zeros(a,b,n); % this will hold the means for each subj X condition
  59. % Calculate means for each subject X condition.
  60. % Keep data in CELLS, because in future we may want to allow options for
  61. % how to compute the means (e.g. leaving out outliers > 3stdev, etc...).
  62. for i=1:a % F1
  63. for j=1:b % F2
  64. for k=1:n % Subjs
  65. INDS{i,j,k} = find(F1==F1_lvls(i) & F2==F2_lvls(j) & S==Subjs(k));
  66. CELLS{i,j,k} = Y(INDS{i,j,k});
  67. MEANS(i,j,k) = mean(CELLS{i,j,k});
  68. end
  69. end
  70. end
  71. % make tables (see table 18.1, p. 402)
  72. AB = reshape(sum(MEANS,3),a,b); % across subjects
  73. AS = reshape(sum(MEANS,2),a,n); % across factor 2
  74. BS = reshape(sum(MEANS,1),b,n); % across factor 1
  75. A = sum(AB,2); % sum across columns, so result is ax1 column vector
  76. B = sum(AB,1); % sum across rows, so result is 1xb row vector
  77. S = sum(AS,1); % sum across columns, so result is 1xs row vector
  78. T = sum(sum(A)); % could sum either A or B or S, choice is arbitrary
  79. % degrees of freedom
  80. dfA = a-1;
  81. dfB = b-1;
  82. dfAB = (a-1)*(b-1);
  83. dfS = n-1;
  84. dfAS = (a-1)*(n-1);
  85. dfBS = (b-1)*(n-1);
  86. dfABS = (a-1)*(b-1)*(n-1);
  87. % bracket terms (expected value)
  88. expA = sum(A.^2)./(b*n);
  89. expB = sum(B.^2)./(a*n);
  90. expAB = sum(sum(AB.^2))./n;
  91. expS = sum(S.^2)./(a*b);
  92. expAS = sum(sum(AS.^2))./b;
  93. expBS = sum(sum(BS.^2))./a;
  94. expY = sum(sum(sum(MEANS.^2))); %sum(Y.^2);
  95. expT = T^2 / (a*b*n);
  96. % sums of squares
  97. ssA = expA - expT;
  98. ssB = expB - expT;
  99. ssAB = expAB - expA - expB + expT;
  100. ssS = expS - expT;
  101. ssAS = expAS - expA - expS + expT;
  102. ssBS = expBS - expB - expS + expT;
  103. ssABS = expY - expAB - expAS - expBS + expA + expB + expS - expT;
  104. ssTot = expY - expT;
  105. % mean squares
  106. msA = ssA / dfA;
  107. msB = ssB / dfB;
  108. msAB = ssAB / dfAB;
  109. msS = ssS / dfS;
  110. msAS = ssAS / dfAS;
  111. msBS = ssBS / dfBS;
  112. msABS = ssABS / dfABS;
  113. % f statistic
  114. fA = msA / msAS;
  115. fB = msB / msBS;
  116. fAB = msAB / msABS;
  117. % p values
  118. pA = 1-fcdf(fA,dfA,dfAS);
  119. pB = 1-fcdf(fB,dfB,dfBS);
  120. pAB = 1-fcdf(fAB,dfAB,dfABS);
  121. % return values
  122. stats = {'Source','SS','df','MS','F','p';...
  123. FACTNAMES{1}, ssA, dfA, msA, fA, pA;...
  124. FACTNAMES{2}, ssB, dfB, msB, fB, pB;...
  125. [FACTNAMES{1} ' x ' FACTNAMES{2}], ssAB, dfAB, msAB, fAB, pAB;...
  126. [FACTNAMES{1} ' x Subj'], ssAS, dfAS, msAS, [], [];...
  127. [FACTNAMES{2} ' x Subj'], ssBS, dfBS, msBS, [], [];...
  128. [FACTNAMES{1} ' x ' FACTNAMES{2} ' x Subj'], ssABS, dfABS, msABS, [], []};
  129. return