Section 11: PROC MIXED and the Output Delivery System (ODS) 1. The ODS and PROC MIXED 2. Producing Graphs of the LSMEANS and their Differences 3. Saving Estimates of Fixed Effects and Exporting to Excel 1. The ODS and PROC MIXED The Output Delivery System (ODS) statements place the contents of tables from PROC MIXED printed to the output window into a SAS datasets. Before reading this section you may want to review a more comprehensive description of the ODS for working with output from SAS procedures found at: http://www.uoregon.edu/~robinh/110_ods.txt You'll need to know the various table names for PROC MIXED and can read there how to determine relevant table names with the ODS TRACE commands. The variety of ODS statements with PROC MIXED can very effectively help you organize and view the output, and are especially necessary when you invoke the diff option on the LSMEANS statement for effects with a large number of levels, or for interactions of variables. Table contents are written to SAS datasets with commands such as: ODS OUTPUT =; You may enter a separate ODS OUTPUT statement for each desired output table or combine them into one. For example, to write the fit statistics (such as AIC Akaike's Information Criterion) to a dataset with an ODS statement enter: ODS OUTPUT FitStatistics=fit; Contents the table you observe printed on the output file with the title "Fit Statistics" are placed in a SAS dataset called "fit" by entering FitStatistics=fit. The ODS EXCLUDE statement prevents the contents of specified tables to be printed to the output. This command may be helpful when working with many factors with LSMEANS and its associated diff option when you have interactions or factors with many levels. ODS EXCLUDE ; Lengthy and difficult to navigate portions of the output -- that produced by DIFFS option with LSMEANS is a prime example -- should almost always be saved to a SAS dataset. You'll find an example that demonstrates how to efficiently print its contents with WHERE statements. Only requested or default output can be converted into a sas datasets. For example, the LSMEANS statement must be present within the PROC MIXED step to produce the dataset with lsmeans and also, the diff option must be included on it as an option to produce a dataset with all pairwise differences for the factors listed. Both the LSMEANS and DIFFS dataset call the variable of interest 'Estimate', which can be confusing when looking at the output. This is the reason for the RENAME= option included on both ODS statements. Also, the variable 'effect' in both datasets can add to the clutter if there is only one fixed effect listed on the LSMEANS statement (it may be helpful to keep it, if there are two or more). For example, * NOTE: enter DROP= on the following statements only if one effect requested; ODS OUTPUT LSMeans=lsm(DROP=effect RENAME=(estimate=lsmean)); ODS OUTPUT Diffs=dfs(DROP=effect RENAME=(estimate=diff_lsmeans)); ODS EXCLUDE diffs lsmeans; PROC MIXED DATA=one method=reml covtest; CLASS group treat subject; MODEL y=group treat group*treat / ddfm=satterth; RANDOM subject(group); LSMEANS group*treat / diff ; *LSMEANS group*treat / diff=control('1' '1'); TITLE1 'MIXED model ANOVA with random effects'; RUN; PROC PRINT DATA=lsm NOobs; VAR group treat lsmean stderr; TITLE2 'Least Squares Means'; run; Degrees of freedom, tvalues, and p-values are also included in the LSMEANS dataset. However, in many situations they are of no interest since they test the hypothesis that the lsmeans equal 0. With all positive measurements, such as height, weight, length, this pvalue only confirms you have 'positive' data. One important situation where they do have meaning is when you are analyzing 'differences' (e.g., pre-test and post-test data). Testing whether mean differences are equal to zero is relevant in those situations. Pairwise Differences of the LSMEANS If you send the differences in LSMEANS to an output window, or print the contents of the dfs file which contains them, you'll see how messy the file with all differences of lsmeans looks. PROC PRINT DATA=dfs NOobs; RUN; All possible pairs of differences in LSMEANS are placed in this file, along with factor levels (two columns for each factor), standard errors, tvalues, df, and pvalues. When printing, it can become difficult to interpret, especially if there are several levels of each factor or with interactions. If you have a significant interaction, you mostly likely will only want to examine pairwise differences in treatments for each level of group. The following PROC PRINT step including both WHERE and VAR statements which print only the comparisons that meet this requirement: * examine all pairwise differences among the treatments within the levels of group; PROC PRINT DATA=dfs NOobs; WHERE (group EQ _group); VAR group treat _treat diff_lsmeans stderr df tvalue probt; TITLE2 'Differences in Least Squares Means'; RUN; These pairwise differences can then be easily associated with the plot of the LSMEANS made previously. 2. Producing Graphs of the LSMEANS and their Differences Plot the LSMEANS with PROC PLOT With 3 groups coded as 1, 2, 3 the scatterplot produced with PROC PLOT shows the relative positions of the LSMEANS for each group with the value of treatment as the plotted symbol: PROC PLOT DATA=lsm; PLOT lsmean * group = treat / haxis = 0 to 4 by 1; OPTIONS ps=35; TITLE2 'LSMEANS for each group/treatment combination'; RUN; QUIT; Plot the LSMEANS with PROC GPLOT PROC GPLOT allows much more flexibility and detail to be observed when plotting lsmeans. Chapter 12 indicates ways to do this yourself. A set of SAS macros to plot lsmeans for 1, 2, or 3 classification or numerical factors can be obtained from: http://www.math.yorku.ca/SCS/sasmac/meanplot.html In the upper-right corner of this page will will see a link to "Utility Macros". From this link you will also need to download the following two macros: panels.sas available from: Utility Macros -> Graphics Utility words.sas available from: Utility Macros -> Macro Utility These three macros can be invoked by entering the following %INCLUDE statement before making the plots: %INCLUDE 'c:\sas\friendly\meanplot.sas'; %INCLUDE 'c:\sas\friendly\panels.sas'; %INCLUDE 'c:\sas\friendly\words.sas'; The words.sas macro is called by the meanplot macro and only needs to exist as an existing macro. Plots of lsmeans can be produced with the meanplot command requesting relevant options; %meanplot(data=lsm, response=lsmean, class=group treatment, xvar=group, cvar=treatment) If you make multiple graphs (see the panel option) you can combine minature versions of them on one graph by entering the %panels macro after %meanplot, that is, enter this statement next: %panels(rows=1, cols=4, equate=Y) Examples how to specify inputs for the meanplot command macro are on the site mentioned above. A plot of the differences is more difficult to produce. How to visually examine them will appear here in the near future. 3. Saving Estimates of Fixed Effects and Exporting to Excel Suppose you want to run several iterations of PROC MIXED and save results of the fixed effect parameters to a dataset and then export to excel or WORD for inclusion in a table. The following list of procedures demonstrates one approach for this task. DATA one; int=10; drop b: ; b1=3; b2=-2; b3=.5; b4=1; b5=4; DO x1 = 1 to 5 by 2; DO x2 = 1 to 5.5 by 1.5; DO HI_ETR = 10 to 50 by 10; DO Lo_ETR = 1 to 3 by 1; DO LOSS = 2 to 4 by .75; Y = int + b1*x1 + b2*x2 + b3*HI_ETR + b4* Lo_ETR + b5* LOSS + rannor(929); output; END; END; END; END; END; PROC PRINT data=one; RUN; * the persist option collects output of the same type into one file across separate runs of the same procedure; ods output SolutionF(persist=proc)=prms; ods listing close; PROC MIXED DATA=one; MODEL Y =x1 x2 HI_ETR /solution; RUN; PROC MIXED DATA=one; model Y=x1 x2 HI_ETR Lo_ETR /solution; RUN; PROC MIXED DATA=one; model Y=x1 x2 Hi_ETR LOSS /solution; RUN; PROC MIXED DATA=one; model Y=x1 x2 HI_ETR Lo_ETR LOSS/solution; RUN; ods output close; ods listing; * all the fixed effects are in the file prms; proc print data=prms; run; * collect the data you want for PROC TABULATE; PROC Format; value ijk 1='Estimate' 2='TValue' 3='Probt'; run; DATA prms2; SET prms; drop estimate tvalue df stderr probt _proc_ _run_; IF (lowcase(substr(effect,1,6))='interc') then jj+1; * the value 'intercept' defines the first row of a new model; model = CATX(' ','Model',jj); i=1 ; y=estimate; output; i=2 ; y=tvalue; output; i=3 ; y=probt; output; proc print; run; * this next ODS statement will send the tabulate output directly to excel, which you can then format to make it appear the way you want it; title1 ; *erase all titles; ods markup tagset=excelxp file='c:\sas\test.xls'; PROC TABULATE DATA=prms2 noseps; CLASS Model effect i / order=data; VAR y; TABLE effect='Variable'*i=' ', model=' ' * y=' ' * sum=' '*F=10.2 / rts=25 misstext=' '; FORMAT i ijk. ; RUN; ODS MARKUP close;