BookmarkSubscribeRSS Feed
asasha
Obsidian | Level 7

I have a table parms that looks like this:

parameter split test1 test2 test3... test10
gini      1      
gini      2       
gini      3
mse       1
mse       2
mse       3

I need to create a macro that would take this table and create a pdf report of 3 pages (a page for each split), each page containing 2 graphs (gini & mse), each graph plotting the values of the tests (10 points). Thank you for your help!

 

8 REPLIES 8
Reeza
Super User

Before you convert code to a macro you need working code, do you have code that creates the report you'd like?

 

I would recommend first doing that. I suspect it'll be easier if you restructure your data as well, to a long format. You can use PROC TRANSPOSE for that.

Transposing data tutorials:
Wide to Long:
https://stats.idre.ucla.edu/sas/modules/how-to-reshape-data-wide-to-long-using-proc-transpose/
https://stats.idre.ucla.edu/sas/modules/reshaping-data-wide-to-long-using-a-data-step/

Then create your base report which would be pretty straightforward IME. 

 

Not exactly sure what the macro part would be since all the data is represented in a report, you could probably just repeat it three times much faster.

 

proc sgplot data=have;
where parameter="gini" and split="1";
series x= testNumber y = testValue;
run;

proc sgplot data=have;
where parameter="mse" and split="1";
series x= testNumber y = testValue;
run;

Here are some macro references to get you started if you really want a macro for some reason.

 

UCLA introductory tutorial on macro variables and macros

https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/

Tutorial on converting a working program to a macro

This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it 🙂 https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md

Examples of common macro usage

https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...

 


@asasha wrote:

I have a table parms that looks like this:

parameter split test1 test2 test3... test10
gini      1      
gini      2       
gini      3
mse       1
mse       2
mse       3

I need to create a macro that would take this table and create a pdf report of 3 pages (a page for each split), each page containing 2 graphs (gini & mse), each graph plotting the values of the tests (10 points). Thank you for your help!

 


 

ballardw
Super User

Actual data would help.

The SAS graphing procedure will work a lot better with data in the form of

 

Parameter  split test_number  test_value

gini             1      1                    123

gini             1      2                    128

gini             1      3                    121

and so forth.

 

Proc transpose can help get it in that form.

Proc SGPANEL will make a separate graph for each level of a BY variable, such as Split and

separate panels for values of Parameter on a Panelby statement.

Why type of plot do you want? Scatter, series, bar, needle, regression? Is the test number supposed to be the xaxis value?

Do you want the two parameter graphs side-by-side , one above the other, or possibly superimposed (both in one graph with two colors to differentiate the parameter)?

 

asasha
Obsidian | Level 7

I would like a simple line graph. The test numbers would be the x axis. Two separate graphs are good (i.e. one above the other). I have no SAS experience. Transpose makes sense! I need it to be a macro that creates one report, as the number of tests could be more (i.e. 50) and the number of splits could be more as well. Each page would represent one split and contain both graphs.

Reeza
Super User
Then after you transpose the data, try the code I've posted. It should generate the line graphs that you want and then you can fuss about with the size and styling to get it perfected. Once you have that done, then you can create a macro to loop through the splits or use CALL EXECUTE(recommended) to run it once for each split as per the tutorial in my first post.
ballardw
Super User

Likely no macro needed.

You should be able to copy and run this code:

data have;
   do parameter='gini','mse';
      do split=1 to 3;
      array test{10};
         do i=1 to dim(test);
            test[i] = 100*rand('uniform');
         end;
         output;
      end;
   end;
run;


proc sort data=have;
   by split parameter;
run;

proc transpose data=have
   out=trans;
   by split parameter;
   var test: ;/* the : immediately after the test
               tells SAS to use all variables starting
               with "test"*/
run;
data forplot;
   set trans;
   Testnumber = input(substr(_name_,5),best.);
run;

proc sgpanel data=forplot;
  by split;
  panelby parameter /rows=2;
  series x=testnumber y=col1;
run;

/* or */
proc sgplot data=forplot;
  by split;
  series x=testnumber y=col1 / group=parameter;
run;

The first data step just makes a data set with some values. Since the test variable values are random the likely do not look like your data.

Sort to get order needed to Transpose.

Then transpose the data.

If your data doesn't have any surprises, like duplicate Parameter/split pairs of values the data will have one output variable named Col1 with the values of the test numbers.

The second data step is to get the test number as a numeric value. Not needed but easier to control axis values with numbers than text if needed.

Then two different approaches to plotting the data as series.

Note, if the input data set has different numbers of tests it still works (change the size of the TEST array in the first data set, splits change the split = 1 to <some other integer>, or parameter, add other parameters in the list quoted and separated by commas. Warning: if you add parameters for testing the LONGEST name needs to be the first one in the list because of the way SAS creates text variables if you do not declare them with a LENGTH statement prior to the first use.

 

To create a PDF of the results the graph code would be placed in an "ods destination sandwich". That is a statement that tells say to start sending data to a file of the specified type and to stop surrounding the output. that generically would look like:

ods pdf file="C:\folder\otherfolder\filenameyouwant.pdf";

<any SAS procedures that create output, Proc Print,
the graph procedure, other procedures >

ods pdf close;  /* stop sending output to the pdf file*/
asasha
Obsidian | Level 7

I tried this and it worked! The only problem I have is the axes range. Both graphs are showing from 0 to 20, so I am getting two straight lines. I need the axis to be in 0.1 - 0.01 increments or so around its average value to see the shape for each metric. 

ballardw
Super User

You can control the displayed axis ranges by using a values statement.

You didn't mention the actual needed range but

rowaxis values =( 0 to 1 by 0.1)

would create 0, 0.1, 0.2 ... 1 axis tick marks on the vertical axis.

If you need to have different ranges for the yaxis you might try UNISCALE=Column in the PANELBY statement. That will allow rows to have different scales but you would not want to use the Values in a rowaxis statement. The rowaxis would set the axis for each row to the specified list. It isn't quite clear which you may need.

 

Generally SAS is pretty good about guesstimating ranges. I would expect one of the values to have a range close to 20, may be above 16.

If you really need to control lots of axis values then that is going to run a lot more programming

asasha
Obsidian | Level 7

Uniscale did the trick, thank you!

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 1190 views
  • 3 likes
  • 3 in conversation