Stata: CONSORT Flowchart

Standard

 

>>Update [2017/08/29]: Check out this nice automated Stata-to-CONSORT flowchart program: https://github.com/IsaacDodd/flowchart/ <<

The CONSORT flowchart for randomised controlled trials has become a standard requirement when publishing medical and social science research (see http://www.consort-statement.org/).

For me it is a regular powerpointpain (e.g. here: http://onlinelibrary.wiley.com/enhanced/doi/10.1111/jsr.12135/). I always thought it would be nice to be able to populate the flow diagram automatically.

I recently figured out how to get Stata to draw stuff. Thus here the flow chart draw by Stata (12.0).

flowchart

CONSORT Flowchart in Stata

CONSORT flowchart in Stata (pdf, high resolution)

And here the do-file, which produced the flowchart, nothing fancy, but maybe helpful:

*Definition of boxes and line styles.
local osmall = 	", box margin(small) size(vsmall)"
local omain =	", box margin(small)"
local bc = ", lwidth(medthick) lcolor(black)" 
local bca = ", lwidth(medthick) lcolor(black) mlcolor(black) mlwidth(medthick) msize(medlarge)"

*Drawing the graph
twoway  /// 1) PCI to draw a box 2) PIC horizontal lines 3) pcarrowi: connecting arrows.
   pci 5.2 0 5.2 6 `bc' || pci 5.2 6 0 6 `bc' || pci 0 6 0 0 `bc' || pci 0 0 5.2 0 `bc' ///
|| pci 3 1.5 3 4.5 `bc' || pci 1.9 1.5 1.9 4.5 `bc' || pci 0.9 1.5 0.9 4.5 `bc' ///
|| pcarrowi 5 3 3.5 3 `bca' ///
|| pcarrowi 4.35 3 4.35 3.35 `bca'  ///
|| pcarrowi 3.5 3 3.2 3 `bca'  ///
|| pcarrowi 3 3 2.1 3 `bca'  ///
|| pcarrowi 1.9 3 1.1 3 `bca'  ///
, /// Text placed using "added text" [ACHTUNG sizes change with content]
text(5 3 "Assessed for eligibility (n= )" `omain') ///
text(4.35 4.5 "Excluded ""(n= )" ///
		"Not meeting inclusion criteria " ///
		"(n= )" ///
		"Declined to participate " ///
		"(n= )" ///
		"Other reasons""(n= )" `osmall') ///
text(3.5 3 "Randomized (n= )" `omain') ///
text(3.1 3 "Allocation"  ) ///
text(2.5 1.5 "ACTIVE" ///
		"Allocated to intervention""(n=)" ///
		"Received allocated intervention ""(n=XXX)" ///
		"Did not receive allocated intervention " ///
		"(give reasons)" ///
		"(n= )" `osmall') ///
text(2.5 4.5 "CONTROL" ///
		 "Allocated to intervention" ///
		 "(n= )""Received allocated intervention " ///
		 "(n= )" /// 
		 "Did not receive allocated intervention " ///
		 "(give reasons)" ///
		 "(n= )" `osmall') ///
text(2 3 "Follow-Up" ) ///
text(1.5 1.5 "Lost to follow-up" ///
	"(give reasons)" ///
	"(n= )" ///
	"Discontinued intervention " ///
	"(give reasons)" ///
	"(n= )" `osmall') ///
text(1.5 4.5 "Lost to follow-up" ///
	"(give reasons)" ///
	"(n= )" ///
	"Discontinued intervention " ///
	"(give reasons)" ///
	" (n= )" `osmall') ///
text(1 3 "Analysis" ) ///
text(0.5 1.5 "Analysed" ///
	"(n= )" ///
	"Excluded from analysis" ///
	"(give reasons)" ///
	"(n= )" `osmall') ///
text(0.5 4.5 "Analysed" ///
	"(n= )" ///
	"Excluded from analysis " ///
	"(give reasons)" ///
	"(n= )" `osmall') /// 
legend(off) ///
xlabel("") ylabel("") xtitle("") ytitle("") ///
plotregion(lcolor(black)) ///
graphregion(lcolor(black)) xscale(range(0 6)) ///
xsize(2) ysize(3) /// A4 aspect ratio
title("Consort Flowchart") ///
note("{bf: Adapted from:} www.consort-statement.org/consort-statement/flow-diagram" ///
, size(tiny))

Anyone who fancies can just put a local to automatically fill the flowchart.

 sum participants if(group == "control")
local allocated control = r(N)
Advertisements

Stata Graphs for Trials: Two Group comparison with confidence intervals (Stata 12.0)

Standard

A) Line graph
alex

Step 1)
Generate a dataset with these variables in long format:
group time levelofoutcome lowerlimit upperlimit

Step 2) Sort time

sort time

Step 3) Draw graph

 line levelofoutcome time if(group==1) , lwidth(thick) ///
 || line lowerlimit time if(group==1) ///
    , lpattern(dash) lwidth(thick) lcolor(blue) ///
 || line upperlimit time if(group==1) ///
    , lpattern(dash) lwidth(thick) lcolor(blue) ///
 || line levelofoutcome time if(group==2) , lwidth(thick) ///
 || line lowerlimit time if(group==2) ///
    , lpattern(dash) lwidth(thick) lcolor(red) ///
 || line upperlimit time if(group==2) ///
    , lpattern(dash) lwidth(thick) lcolor(red) ///
 || scatter levelofoutcome time , mcolor(black) ///
 xlabel( 1 "Baseline" 2 "Postintervention") ///
 xscale( range(0.75 2.25)) ///
 legend( ///
        order(1 2 4 5) ///
        label(1 "Group A") label(2 "95% CI") ///
        label(4 "Group B") label(5 "95% CI") ///
       )

B) Bargraph

Two groups, bargraphs, confidence intervals at baseline/post-intervention

Two groups, bargraphs, confidence intervals at baseline/post-intervention

Step 1) Sort time AND group.

 sort  time group

Step 2) Generate a variable which provides the positions of the bars
in the graph.

 gen barposition = cond(time==1, _n, _n+1)

The “+1” generates the gap between the two sets of bars (time 1/time2).

Step 3) Draw graph over “bar position” variable.
Use [rcap] to draw confidence intervals.
To have different bar colours per group, draw them separately using [if(group=== X)]

 twoway bar  levelofoutcome barposition  if(group==1) ///
	|| bar  levelofoutcome barposition  if(group==2) ///
	|| rcap  lowerlimit upperlimit barposition 		 ///
	,lwidth(medthick) lcolor(black) msize(huge) ///
	, yscale(range(45 75)) xscale(range(0 6))  ///
	xlabel( 1.5 "Baseline" 4.5 "Postintervention") ///
	legend( ///
			cols(3) ///
			label(1 "Group A") ///
			label(2 "Group B") ///
			label(3 "95% CI")  ///
			) ///
	xtitle("Trial results") ytitle("Level of outcome")

C) Point estimates with confidence intervals.

Two groups, point estimates, confidence intervals at baseline/post-intervention

Two groups, point estimates, confidence intervals at baseline/post-intervention

Use first two steps of the “bargraph” and then a scatter plot instead of [twoway bar]

scatter  levelofoutcome barposition  if(group==1) ///
		,msymbol(D) msize(large) ///
	|| scatter  levelofoutcome barposition  if(group==2) ///
		,msymbol(S) msize(large) ///
	|| rcap  lowerlimit upperlimit barposition 		 ///
	,lwidth(medthick) lcolor(black) msize(huge) ///
	, yscale(range(45 75))   xscale(range(0 6))  ///
	xlabel( 1.5 "Baseline" 4.5 "Postintervention") ///
	legend( ///
			cols(3) ///
			label(1 "Group A") ///
			label(2 "Group B") ///
			label(3 "95% CI")  ///
			) ///
	xtitle("Trial results") ytitle("Level of outcome")

Data:
example_data_linegraph

Reference:

The trick for positioning bars/pointestimates comes from: UCLA on bargraphs with with errors in Stata