Data visualization with SAS programming

Consort Diagram Question

Reply
Occasional Contributor
Posts: 6

Consort Diagram Question

Good Afternoon,

 

I found this code from Sanjay's Graphically Speaking Blog, and I cannot get it to work. Does anyone else know any tips or tricks to get it to work?

 

http://blogs.sas.com/content/graphicallyspeaking/files/2016/10/Consort_Diagram.txt

 

%let gpath='.';
ods html close;
%let dpi=200;
ods listing gpath=&gpath image_dpi=&dpi;

/*--Node Data for Diagram--*/
data nodes;
  input NodeId  Xn  Yn;
  datalines;
 0  30  200 
 1  30  190
 2  30  180
 3  50  180
 4  30  170
 5  30  160 
 6  20  150
 7  30  150
 8  40  150
 9  60  150
10  80  150
11  20  140
12  40  140
13  60  140
14  80  140
15  20  100
16  40  100
17  60  100
18  80  100
19  20   90
20  40   90
21  60   90
22  80   90
23  20   50
24  40   50
25  60   50
26  80   50
27  20   40
28  40   40
29  60   40
30  80   40
;
run;

/*--Create Node Hash Table--*/
data _null_;
  length NodeId Xn Yn 8;
  set Nodes end=last;

  /* Declare the hash object for Nodes and Links */
  if _n_ = 1 then do;
     declare hash nodes( ordered:'a');
     rc = nodes.defineKey('NodeId');
     rc = nodes.defineData('NodeId', 'Xn', 'Yn');
     rc = nodes.defineDone();
  end;

  /*--If node is not already in the table, add it.--*/
  rc=nodes.find();
  if rc ne 0 then do;
    nodes.add();
  end;

  /*--Save Node and Link hash tables--*/
  if last then do;
    rc = nodes.output(dataset: "work.ConsortNodes");
  end;
run;

/*--Link Data for Diagram--*/
data links;
  input LinkId  N1  N2  N3  N4; 
  datalines;
 1   1   4   .    .
 2   2   3   .    .
 3   5   7   6   11 
 4   7   8  12    .
 5   8   9  13    .
 6   9  10  14    .
 7  15  19   .    .
 8  16  20   .    .
 9  17  21   .    .
10  18  22   .    .
11  23  27   .    .
12  24  28   .    .
13  25  29   .    .
14  26  30   .    .
;
run;

/*--Find Link vertex data from Node data--*/
data links2;
  keep LinkId Xl Yl;
  length NodeId Xn Yn 8;

  set links end=last;

  /* Declare the hash object for Nodes from data set */
  if _n_ = 1 then do;
     declare hash nodes( dataset:'work.ConsortNodes', ordered:'a');
     rc = nodes.defineKey('NodeId');
     rc = nodes.defineData('NodeId', 'Xn', 'Yn');
     rc = nodes.defineDone();
  end;

  /*--Set N1 node location--*/
  if n1 ne . then do;
    NodeId=n1;
    rc=nodes.find();
    if rc eq 0 then do;
      xl=xn; yl=yn; output;
	end;
  end;

  /*--Set N2 node location--*/
  if n2 ne . then do;
    NodeId=n2;
    rc=nodes.find();
    if rc eq 0 then do;
      xl=xn; yl=yn; output;
	end;
  end;

  /*--Set N3 node location--*/
  if n3 ne . then do;
    NodeId=n3;
    rc=nodes.find();
    if rc eq 0 then do;
      xl=xn; yl=yn; output;
	end;
  end;

  /*--Set N4 node location--*/
  if n4 ne . then do;
    NodeId=n4;
    rc=nodes.find();
    if rc eq 0 then do;
      xl=xn; yl=yn; output;
	end;
  end;

run;

/*--Empty Box Data--*/
data Emptyboxes;
  input epid xp yp;
  datalines;
 1  15  200
 1  45  200
 1  45  190
 1  15  190

 2  15  170
 2  45  170
 2  45  160
 2  15  160

 3  50  195
 3  80  195
 3  80  165
 3  50  165

 4  11  140
 4  29  140
 4  29  100
 4  11  100
 5  31  140
 5  49  140
 5  49  100
 5  31  100
 6  51  140
 6  69  140
 6  69  100
 6  51  100
 7  71  140
 7  89  140
 7  89  100
 7  71  100

 8  11   90
 8  29   90
 8  29   50
 8  11   50
 9  31   90
 9  49   90
 9  49   50
 9  31   50
10  51   90
10  69   90
10  69   50
10  51   50
11  71   90
11  89   90
11  89   50
11  71   50

12  11   40
12  29   40
12  29    0
12  11    0
13  31   40
13  49   40
13  49    0
13  31    0
14  51   40
14  69   40
14  69    0
14  51    0
15  71   40
15  89   40
15  89    0
15  71    0
;
run;

/*--Filled Box Data--*/
data Filledboxes;
  input fpid xp yp;
  datalines;
16   4  195
16   9  195
16   9  155
16   4  155

17   4  140
17   9  140
17   9  100
17   4  100

18   4   90
18   9   90
18   9   50
18   4   50

19   4   40
19   9   40
19   9    0
19   4    0
;
run;

/*--Horizontal text Center Aligned--*/
data htextc;
  input  xt   yt  htextc $10-75;
  datalines;
30  195   Assessed for Eligibility (n=445)
30  165   Randomized (n=406)
;
run;

/*--Horizontal text Left Aligned--*/
data htextl;
  input  xt   yt  htextl $10-125;
  datalines;
50  180   Excluded (n=39).- Not meeting inclusion criteria (n=22).- Declined to participate (n=14).- Other reasons (n=3)
11  120   Allocated to Placebo. (n=96).- Received allocated.  drug (n=90).- Did not receive.  allocated drug (n=6)
;
run;

/*--Vertical text for stage labels--*/
data vtext;
  input  xt   yt  vtext $10-75;
  datalines;
 6  175   Enrollment
 6  120   Allocation
 6   70   Follow-Up
 6   20   Analysis
;
run;

/*--Combine data--*/
data consort;
  set nodes links2 emptyboxes filledboxes htextc htextl vtext;
run;

/*--Draw the Consort Diagram--*/
ods graphics / reset width=6in height=4in imagename='Consort';
title 'Consort Diagram for Displaying Counts';
proc sgplot data=consort noborder noautolegend;
  series x=xl y=yl / group=linkid lineattrs=graphdatadefault 
         arrowheadpos=end arrowheadshape=barbed arrowheadscale=0.4;
  polygon id=epid x=xp y=yp;
  polygon id=fpid x=xp y=yp / fill outline 
          fillattrs=(color=cx4f6f9f) lineattrs=(color=cx2f3f5f);
  text x=xt y=yt text=htextc / splitchar='.' splitpolicy=splitalways;
  text x=xt y=yt text=htextl / splitchar='.' splitpolicy=splitalways position=right;
  text x=xt y=yt text=vtext / rotate=90 textattrs=(size=9 color=white);
  xaxis display=none min=0 max=90 offsetmin=0 offsetmax=0;
  yaxis display=none min=0 max=200 offsetmin=0 offsetmax=0;
run;
SAS Super FREQ
Posts: 1,139

Re: Consort Diagram Question

[ Edited ]

I just cut-n-pasted the code you included into SAS 9.4M3, and it worked like a charm.  Output below.

 

Consort.png

Occasional Contributor
Posts: 6

Re: Consort Diagram Question

This is the error message I got in the log:


274
275 /*--Draw the Consort Diagram--*/
276 ods graphics / reset width=6in height=4in imagename='Consort';
277 title 'Consort Diagram for Displaying Counts';
278 proc sgplot data=consort noborder noautolegend;
279 series x=xl y=yl / group=linkid lineattrs=graphdatadefault
280 arrowheadpos=end arrowheadshape=barbed arrowheadscale=0.4;
------------
22
76
ERROR 22-322: Syntax error, expecting one of the following: ;, (, ATTRID, BREAK, CLUSTERWIDTH,
CURVELABEL, CURVELABELATTRS, CURVELABELLOC, CURVELABELPOS, DATALABEL,
DATALABELATTRS, DATALABELPOS, DATASKIN, DISCRETEOFFSET, FILLEDOUTLINEDMARKERS,
GROUP, GROUPDISPLAY, GROUPORDER, LEGENDLABEL, LINEATTRS, MARKERATTRS,
MARKERFILLATTRS, MARKEROUTLINEATTRS, MARKERS, NAME, NOMISSINGGROUP, SMOOTHCONNECT,
SPLITCHAR, SPLITCHARNODROP, SPLITJUSTIFY, TIP, TIPFORMAT, TIPLABEL, TRANSPARENCY,
URL, X2AXIS, Y2AXIS.
ERROR 76-322: Syntax error, statement will be ignored.
281 polygon id=epid x=xp y=yp;
282 polygon id=fpid x=xp y=yp / fill outline
283 fillattrs=(color=cx4f6f9f) lineattrs=(color=cx2f3f5f);
284 text x=xt y=yt text=htextc / splitchar='.' splitpolicy=splitalways;
----
180
285 text x=xt y=yt text=htextl / splitchar='.' splitpolicy=splitalways position=right;
----
180
286 text x=xt y=yt text=vtext / rotate=90 textattrs=(size=9 color=white);
----
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
287 xaxis display=none min=0 max=90 offsetmin=0 offsetmax=0;
288 yaxis display=none min=0 max=200 offsetmin=0 offsetmax=0;
289 run;

NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SGPLOT used (Total process time):
real time 0.06 seconds
cpu time 0.01 seconds

 

SAS Super FREQ
Posts: 925

Re: Consort Diagram Question

Instead of using the SERIES statement, try using the SPLINE statement and see if that works for you.

 

Thanks!

Dan

Super User
Posts: 19,105

Re: Consort Diagram Question

What version of SAS do you have?
Occasional Contributor
Posts: 6

Re: Consort Diagram Question

SAS 9.4
SAS Super FREQ
Posts: 1,139

Re: Consort Diagram Question

If you have V9.4, and not V9.40M3, you may need to change the following:

  1. Use VECTOR plot instead of SERIES since series may not have the arrowhead feature at V9.4.
  2. Use SCATTER with MARKERCHAR instead of TEXT.

 

Then, see what else the grammar parser does not like.

New Contributor
Posts: 2

Re: Consort Diagram Question

Hi Sanjay,

 

If I used  SCATTER with MARKERCHAR instead of TEXT, would it be possible to left align (instead of center) the text? Thanks.

 

Thanks,

Tracy

SAS Super FREQ
Posts: 1,139

Re: Consort Diagram Question

SGPLOT does not support positioning of the text string.  However, GTL does.  So, you can try coding up the SGPLOT program using MARKERCHAR, and then get the generated GTL code using the TMPLOUT option.  Then, you can edit the GTL template syntax, and insert the MARKERCHARACTERPOSITION=LEFT option.  This should work with SAS 9.4.

New Contributor
Posts: 2

Re: Consort Diagram Question

Yes, TMPLOUT + "MARKERCHARACTERPOSITION=right" (not sure why not "left") + proc SGRENDER worked. Thanks Sanjay!

SAS Super FREQ
Posts: 1,139

Re: Consort Diagram Question

I recall now...it is position of the string wrt the (x, y) location.  So, to justify left, you need to draw to the right of points with constant x value.  So, that is correct.

SAS Super FREQ
Posts: 3,626

Re: Consort Diagram Question

Anytime you say "I cannot get it to work" you need to supply the error message or output so that we know what you are seeing.  For error messages, it is best to post the portion of the SAS log that contains the code and error message.

Ask a Question
Discussion stats
  • 11 replies
  • 275 views
  • 1 like
  • 6 in conversation