BookmarkSubscribeRSS Feed
WendyT
Pyrite | Level 9

SAS folks-

I need your help again.  I have been poring over the documentation and lots of papers, and have managed to rework some old GPLOT code into SGPLOT.  Now I have some nicely titled graphics that update on a weekly basis via a batch on scheduled task.

It creates a set of graphics with combinations of parameters over a timeframe that updates based on the current date for a number of station locations.  The station and timeframe selections change on a frequent basis, so I do my final data selection before starting the graphics, use a BY statement for the stations, and MIN and MAX with macro variables on an AXIS statement for the timeframe.  

In the old GPLOT graphics, all the different plots for one sampling station were together.  With SGPLOT, the graphics of the same type are together, and the stations are separated.  With my current settings, I am generating 378 graphics files, so it’s not a small output.  

My folks would now like me to display the graphics both ways, in the same HTML frame with the parameter grouping first and the station grouping second.  This should be a perfect application for PROC DOCUMENT. Using links instead of generating a second set of graphics files would also be ideal. I also had a shot at turning it into a macro, getting information from the dataset.

I have been able to set up the ODS DOCUMENT, and rearrange the output using LINK. However, when I output the modified DOCUMENT to HTML, it generates a duplicate set of graphics files.

Also, I can’t figure out where there is some sort of table (view or whatever) with the DOCUMENT information.  My current macro requires coding of all the links for one set, so that would change every time I add or delete a set of graphics.

I’m sure there is a much better way to do this, and I’m stuck on what to try next to eliminate the double graphic files, or how to make the rearrangement macro better.  I’m the rearrangement will  become a standard feature on output, so I’m trying to make it as painless as possible. 

ODS is confusing me as well.  I can get ODS PROCLABEL to work, but not ODS NOPROCTITLE to get rid of ‘The SGPlot Procedure.’  I’m also unclear on why I need the third level directory to display the value of &&VARVAL&INDEX in the table of contents.

I set up a similar example using SASHELP.STOCKS (below), and I have attached (most of) the log and one of the graphic files (limit of 4 files).

We are running 9.3 with the output defaults set back to the 9.2 defaults, on a server with Windowns 2008 Enterprise, so I do not have access to the registry.

Any help you can give me would be very welcome!

Wendy T.

%LET OUTDIR=&temp_output/graphics ;

%LET DSN=SASHELP.STOCKS ;

*delete all files from output directory ;

systask command "del ""&outdir\*.* "" ";

*delete all existing graphics from WORK.GSEG ;

%macro delcat(catname);

  %if %sysfunc(cexist(&catname)) %then %do;

    proc greplay nofs igout=&catname;

     delete _all_;

    run;

  %end;

quit;

%mend delcat;

%delcat(GSEG) ;

* find begin and end dates of dataset and extend one month each way ;

PROC SQL NOPRINT ;

  SELECT MIN(DATE)               INTO :NUM_MINDATE FROM &DSN ;

  SELECT MAX(DATE)               INTO :NUM_MAXDATE FROM &DSN ;

  SELECT MIN(DATE) FORMAT DATE9. INTO :MINDATE FROM &DSN ;

  SELECT MAX(DATE) FORMAT DATE9. INTO :MAXDATE FROM &DSN ;

QUIT ;

RUN ;

%LET START_MONTH=%sysfunc(intnx(month,(&NUM_MINDATE),-1),DATE9.);

%LET END_MONTH=%sysfunc(intnx(month,(&NUM_MAXDATE),+1),DATE9.);

%PUT &NUM_MINDATE &MINDATE &NUM_MAXDATE &MAXDATE &START_MONTH &END_MONTH ;

RUN ;

OPTIONS NOBYLINE ;

title ;

footnote1 JUSTIFY=LEFT "Time series data from &START_MONTH to &END_MONTH on dataset &DSN run on &SYSDATE";

ODS _ALL_ CLOSE ;

%LET BASE=TS_GRAFS ;

ODS TRACE ON ;

ODS DOCUMENT NAME=WORK.STOCK_GRAPHS(WRITE) ;

ODS NOPROCTITLE ;

ODS GRAPHICS ONRESET=ALL IMAGENAME="GRAF_" HEIGHT=480px WIDTH=1280px ;

ODS PROCLABEL='Open and Close with Volume' ;

PROC SGPLOT DATA=&DSN  ;

BY STOCK ;

TITLE " #BYVAL(STOCK) Stock" ;

SERIES X=DATE Y=OPEN   /        BREAK MARKERS LINEATTRS= (PATTERN=1MARKERATTRS= (SYMBOL=CircleFilled) ;

SERIES X=DATE Y=CLOSE  /        BREAK MARKERS LINEATTRS= (PATTERN=1MARKERATTRS= (SYMBOL=Circle)       ;

SERIES X=DATE Y=VOLUME / Y2AXIS BREAK MARKERS LINEATTRS= (PATTERN=1MARKERATTRS= (SYMBOL=Triangle)     ;

KEYLEGEND / LOCATION=INSIDE POSITION=TOPLEFT ;

XAXIS TYPE=TIME INTERVAL=AUTO MINOR MIN="&START_MONTH"D   MAX="&END_MONTH"D ;

YAXIS LABEL='Open and Close ($)' ;

Y2AXIS LABEL='Volume'  ;

RUN ;

ODS PROCLABEL='High Low and Close with Volume' ;

PROC SGPLOT DATA=&DSN ;

BY STOCK ;

TITLE " #BYVAL(STOCK) Stock" ;

SERIES X=DATE Y=HIGH   /        BREAK MARKERS LINEATTRS= (PATTERN=1MARKERATTRS= (SYMBOL=CircleFilled) ;

SERIES X=DATE Y=LOW    /        BREAK MARKERS LINEATTRS= (PATTERN=1MARKERATTRS= (SYMBOL=Circle)       ;

SERIES X=DATE Y=VOLUME / Y2AXIS BREAK MARKERS LINEATTRS= (PATTERN=1MARKERATTRS= (SYMBOL=Triangle)     ;                            

SERIES X=DATE Y=CLOSE  /        BREAK         LINEATTRS= (PATTERN=1)                                     ;

KEYLEGEND / LOCATION=INSIDE POSITION=TOPLEFT ;

XAXIS TYPE=TIME INTERVAL=AUTO MINOR MIN="&START_MONTH"D   MAX="&END_MONTH"D ;

YAXIS LABEL='High, Low, and Close ($)' ;

Y2AXIS LABEL='Volume'  ;

RUN ;

ODS DOCUMENT CLOSE ;

%MACRO RESORT_GRAPHS(DSN,VAR_NAME,MOD_DOC) ;

PROC SQL NOPRINT ;

  SELECT DISTINCT &VAR_NAME INTO :VARVAL1- FROM &DSN ;

    %LET VARCOUNT=&SQLOBS ;

QUIT ;

PROC DOCUMENT ;

DOC NAME=&MOD_DOC.(UPDATE) ;

  MAKE &VAR_NAME ;

  

  %do index = 1 %to &varCount;

    MAKE \&VAR_NAME.\&&VARVAL&INDEX ;

    MAKE \&VAR_NAME.\&&VARVAL&INDEX.\DUMMY ;

      LINK \&MOD_DOC.\Sgplot#1\ByGroup1#1\SGPlot#1 to \&VAR_NAME.\&&VARVAL&INDEX.\DUMMY ;

      LINK \&MOD_DOC.\Sgplot#2\ByGroup1#1\SGPlot#1 to \&VAR_NAME.\&&VARVAL&INDEX.\DUMMY ;

  %END ;

DOC CLOSE ;

RUN ;

QUIT ;

ODS DOCUMENT CLOSE ;

%MEND ;

%RESORT_GRAPHS(SASHELP.STOCKS,STOCK,WORK.STOCK_GRAPHS) ;

ODS _ALL_ CLOSE ;

ODS HTML newfile=none headtext='<style>p,hr {display:none} </style>' STYLE=styles.default

    PATH="&OUTDIR\" (URL=NONE)

    body="body_&BASE..htm" (TITLE="GRAF_OUTPUT") contents="contents_&BASE..htm" frame="frame_&BASE..html" ;

PROC DOCUMENT NAME=STOCK_GRAPHS ;

REPLAY ;

LIST / LEVELS=ALL ;

RUN;

QUIT ;

ODS _ALL_ CLOSE ;

ODS LISTING ;


GRAF_.png
2 REPLIES 2
will781
Calcite | Level 5

To get rid of "The SGPlot Proecude" try the sgplot option DESCRIPTION= "text-string"

WendyT
Pyrite | Level 9

Folks- I've been messing with this again, and have finally come up with a solution, but it still could use improvement.

I have come up with the following macro:

%MACRO RESORT_GRAPHS(DSN,VAR_NAME,FROM_DOC,TO_DOC) ;

PROC SQL NOPRINT ;

SELECT DISTINCT &VAR_NAME INTO :VARVAL1- FROM &DSN ;  

%LET VARCOUNT=&SQLOBS ;

QUIT ;

PROC DOCUMENT ;

  DOC NAME=&TO_DOC.(WRITE) ;

    MAKE &VAR_NAME ;  

     %do index = 1 %to &varCount;  

        MAKE \&VAR_NAME.\&&VARVAL&INDEX ;  

        MAKE \&VAR_NAME.\&&VARVAL&INDEX.\&VAR_NAME ;    

            COPY \&FROM_DOC.\Sgplot#1\ByGroup&INDEX.#1\SGPlot#1 to \&TO_DOC\&VAR_NAME.\&&VARVAL&INDEX.\&VAR_NAME ;    

            COPY \&FROM_DOC.\Sgplot#2\ByGroup&INDEX.#1\SGPlot#1 to \&TO_DOC\&VAR_NAME.\&&VARVAL&INDEX.\&VAR_NAME ;    

            COPY \&FROM_DOC.\Sgplot#3\ByGroup&INDEX.#1\SGPlot#1 to \&TO_DOC\&VAR_NAME.\&&VARVAL&INDEX.\&VAR_NAME ;    

            COPY \&FROM_DOC.\Sgplot#4\ByGroup&INDEX.#1\SGPlot#1 to \&TO_DOC\&VAR_NAME.\&&VARVAL&INDEX.\&VAR_NAME ;    

            COPY \&FROM_DOC.\Sgplot#5\ByGroup&INDEX.#1\SGPlot#1 to \&TO_DOC\&VAR_NAME.\&&VARVAL&INDEX.\&VAR_NAME ;    

            COPY \&FROM_DOC.\Sgplot#6\ByGroup&INDEX.#1\SGPlot#1 to \&TO_DOC\&VAR_NAME.\&&VARVAL&INDEX.\&VAR_NAME ;    

            COPY \&FROM_DOC.\Sgplot#7\ByGroup&INDEX.#1\SGPlot#1 to \&TO_DOC\&VAR_NAME.\&&VARVAL&INDEX.\&VAR_NAME ;

    %END ;

           COPY \&FROM_DOC.\Print#1\Print#1 to \&TO_DOC\^^ ;

DOC CLOSE ;

RUN ;

QUIT ;

ODS DOCUMENT CLOSE ;

%MEND ;

%RESORT_GRAPHS(GRAPH1,STATION,WORK.GROUP_GRAPHS,WORK.STATION_GRAPHS) ;

DSN is the GRAPH1 dataset, STATION is the variable I want to use (name of sampling location), and then the ODS document names. Currently, I have 7 different types of graphics run with various parameters, and I would like to resort them to have all 7 graphics for one station (location) together. The above macro worked fine on my first station list, which was all character.

However, I have an additional station list where the station is all numbers, and the path errors out with the numbers.  I can hardcode in a character, but that could cause some problems with folks thinking the character is part of the name.

Help!

WendyT

From my log:

5591  %RESORT_GRAPHS(GRAPH1,STATION,WORK.GROUP_GRAPHS,WORK.STATION_GRAPHS) ;

MPRINT(RESORT_GRAPHS): PROC SQL NOPRINT ;

MPRINT(RESORT_GRAPHS):  SELECT DISTINCT STATION INTO :VARVAL1- FROM GRAPH1 ;

MPRINT(RESORT_GRAPHS):  QUIT ;

NOTE: PROCEDURE SQL used (Total process time):       real time          0.01 seconds     

user cpu time      0.00 seconds     

system cpu time    0.01 seconds     

memory              2528.79k     

OS Memory          77692.00k     

Timestamp          04/01/2013 01:51:50 PM

MPRINT(RESORT_GRAPHS):  PROC DOCUMENT ;

MPRINT(RESORT_GRAPHS):  DOC NAME=WORK.STATION_GRAPHS(WRITE) ;

MPRINT(RESORT_GRAPHS):  MAKE STATION ;

NOTE: Line generated by the macro variable "VARVAL1".

1      02248000

       --------     

       22     

       200

MPRINT(RESORT_GRAPHS):  MAKE \STATION\02248000 ;

NOTE: The previous statement has been deleted.

NOTE: Line generated by the macro variable "VARVAL1".

1      02248000

       --------

       22

       200

MPRINT(RESORT_GRAPHS):  MAKE \STATION\02248000\STATION ;

NOTE: The previous statement has been deleted.

NOTE: Line generated by the macro variable "VARVAL1".

1      02248000

       --------

       22

       200

MPRINT(RESORT_GRAPHS):  COPY \WORK.GROUP_GRAPHS\Sgplot#1\ByGroup1#1\SGPlot#1 to \WORK.STATION_GRAPHS\STATION\02248000\STATION ;

NOTE: The previous statement has been deleted.

NOTE: Line generated by the macro variable "VARVAL1".

1      02248000

       --------

       22

       200

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 1058 views
  • 0 likes
  • 2 in conversation