BookmarkSubscribeRSS Feed
JeffMeyers
Barite | Level 11

One of my favorite things to do is to write macros to make tables/graphics/reports/etc.  Some of my best ones can be found on this site (NEWSURV, MVMODELS, TABLEN, CIRCOS, DATA_SPECS, COMPARE_ALL), and a new one that I have been developing has focused on making a Consort diagram.  In the past I've had to use software like Word, Visio, and PowerPoint to make these diagrams as I hadn't found a way to do it programmatically.  I've seen cases where an RTF document somehow has numbers filled in to an existing chart, but didn't like that approach.

 

My macro focuses on using TEXT plots to make the text boxes and then connects them with line statements based on the anchors of the text boxes.  Here is an example of one that I made with my current macro:

_consort.png

 The macro call that I needed to use to make this was:

%consort(data=for_consort,id=subject,
    node=screened randomized treated ntrt4 ntrt8 ntrtv2 surg adj compadj, 
    split=* arm,
    offreason=scrnrsn endatrsn endrsn2)

The options stand for:

  • DATA: one row per patient data set where the variables to be used in NODE live
  • ID: patient ID variable used for counts
  • NODE: list of variables that determine the different nodes (or boxes) in the consort. e.g. randomization, went to surgery, etc.  The value of the variable is used as the text in the text box.  Should only be one unique value within each branch of the consort.  If a patient doesn't exist in the node then the value should be missing for that variable.
  • SPLIT: Determines when the consort will split.  Currently only works with one split, but am working to make it work with more.  The node will still be shown (randomization in the above example), and then the split will happen and the counts will be shown for each level of the SPLIT variable.  * indicates no split, and the last value of split is carried forward through further nodes if left missing
  • OFFREASON: When a patient is found in one node but not in the following node, they are counted as going "off treatment" and placed into a box branching from the consort.  The reasons listed in the box are pulled from these variables, with the label of the variable being used as the header for the text box.  The last variable is carried forward through further nodes if left missing.

The macro calculates the x/y coordinates of the boxes as well as the lines that connect them before drawing.  There are also methods within the macro to manually make the dataset for more complicated consorts.

 

My questions are:

  1. Does the macro call make sense to use? 
  2. What are features that you would want in a consort diagram macro?
  3. Has this already been done before?  I've seen SAS programs from SAS workers but not using the same methodology or automation

Any feedback or suggestions are appreciated!  I've been rather excited by the challenge of making this program.

 

6 REPLIES 6
Norman21
Lapis Lazuli | Level 10

Very interesting.

 

1. Yes, this looks useful. As a suggestion, try and make output look like the following: http://www.consort-statement.org/consort-statement/flow-diagram

 

2. It would be useful to have a check on the numbers to ensure they add up correctly. For example, started adjuvant treatment n=22 minus off treatment n=3 should equal completed adjuvant treatment n=19. Also, it would be good to have output options e.g. PDF or RTF.

 

3. Yes - see https://www.phusewiki.org/docs/Conference%202016%20PP%20Papers/PP03.pdf

Norman.
SAS 9.4 (TS1M6) X64_10PRO WIN 10.0.17763 Workstation

JeffMeyers
Barite | Level 11
Thank you for the feedback and suggestions. I'm still experimenting with putting in additional features like different kinds of bullet points and those sub-header style boxes in the example you showed. I'll definitely keep the reference in mind.

For number two the macro doesn't take input on the off treatment boxes. It compares which patients were in the previous node (started adjuvant treatment) that are not in the current node (completed adjuvant treatment) and files them into the off treatment box using the OFFREASON variable for the reason why. I'm trying to automate this as much as possible. Even if the off treatment variable is missing they would still be included in the off treatment box.
Jianmin
Obsidian | Level 7

Hi @JeffMeyers and @Norman21 , 

 

It's a great effort of Jeffrey to try an automated solution for this very difficult task, and the outcome so far is very helpful and promising.  I agree with Norman21 on 1) and 2).  3. has a bad link, and it probably refers to a Prashant Hebbar's paper, and here is one: https://www.sas.com/content/dam/SAS/support/en/sas-global-forum-proceedings/2019/3149-2019.pdf . 

 

Hebba's work was amazing but not general enough and it's not about to automate this process.  

 

Shane Rosanbalm' work, of Rho Inc.,  https://www.lexjansen.com/pharmasug/2019/DV/PharmaSUG-2019-DV-021.pdf,  is very closed to automate the process, he wrote 3 macros to handle the boxes, links and text positions and they are quite general.

 

Ryan Yu, of Regeneron, published a paper to claim he automated the process, using Shane's macros, https://www.lexjansen.com/pharmasug/2021/DV/PharmaSUG-2021-DV-082.pdf, but we haven't see the code yet. 

 

Besides 1. and 2 from Norman21, Figure 3 in this link: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2222221/pdf/1745-6215-8-36.pdf is a little bit challenge for Jeffrey to try. 

 

I have explored a different method to draw a CONSORT diagram.  See the attached.  It uses Microsoft Word/RTF's Shapes, boxes and arrows here and only SAS data _null_ was used in the generation of the file.  The outcome is an RTF file, but it's totally not what in Art Carpenter's head when he talked about using RTF file to automation of CONSORT diagram: https://www.lexjansen.com/pharmasug/2012/TF/PharmaSUG-2012-TF16.pdf

 

JeffMeyers
Barite | Level 11
It doesn't show up in searches easily, but I presented my mostly finished macro at the global forum this year:
https://communities.sas.com/t5/SAS-Global-Forum-Proceedings/Methods-of-a-Fully-Automated-CONSORT-Dia...
Quentin
Super User

Definitely useful. 

 

Suggest you see similar:

https://www.sas.com/content/dam/SAS/support/en/sas-global-forum-proceedings/2019/3149-2019.pdf

https://blogs.sas.com/content/graphicallyspeaking/2016/10/20/outside-box-consort-diagram/

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
JeffMeyers
Barite | Level 11
Thank you! I got to attend Prashant's talk and it inspired me to try to code it myself! I love picking up fun new ideas at conferences.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 6 replies
  • 1226 views
  • 7 likes
  • 4 in conversation