options nocenter ps=64 ls=80;		/* Two-Way Random Effects Model */
data twoway;
   infile 'random.dat';			/* MJ 18/19 */
   input row col y;

proc glm;				/* THE OLD PROC GLM */
   class row col;
   model y = row col row*col / ss1 ss2 ss3 solution;
   random row col row*col / test;
   estimate 'grand mean' intercept 1;
   estimate 'row 1 col 1' intercept 1 row 1 col 1 row*col 1;
   estimate 'row 1 col 2' intercept 1 row 1 col 0 1 row*col 0 1;
   estimate 'row 1 col 3' intercept 1 row 1 col 0 0 1 row*col 0 0 1;
   estimate 'row 2 col 1' intercept 1 row 0 1 col 1 row*col 0 0 0 1;
   estimate 'row 2 col 2' intercept 1 row 0 1 col 0 1 row*col 0 0 0 0 1;
   estimate 'row 2 col 3' intercept 1 row 0 1 col 0 0 1 row*col 0 0 0 0 0 1;

proc varcomp;				/* THE BETTER PROC VARCOMP */
   class row col;
   model y = row col row*col;
proc varcomp method=type1;
   class row col;
   model y = row col row*col;
proc varcomp method=ml;
   class row col;
   model y = row col row*col;
proc varcomp method=reml;
   class row col;
   model y = row col row*col;

proc mixed;				/* THE NEW PROC MIXED */
   class row col;
   model y = ;
   random row col row*col / solution;
   estimate 'grand mean' intercept 1;
   estimate 'row 1 col 1' intercept 1 | row 1 col 1 row*col 1;
   estimate 'row 1 col 2' intercept 1 | row 1 col 0 1 row*col 0 1;
   estimate 'row 1 col 3' intercept 1 | row 1 col 0 0 1 row*col 0 0 1;
   estimate 'row 2 col 1' intercept 1 | row 0 1 col 1 row*col 0 0 0 1;
   estimate 'row 2 col 2' intercept 1 | row 0 1 col 0 1 row*col 0 0 0 0 1;
   estimate 'row 2 col 3' intercept 1 | row 0 1 col 0 0 1 row*col 0 0 0 0 0 1;
