/*** DO NOT EDIT THIS LINE ----------------------------------------------------- Title: makediagram Description: generates DOT diagram file from data sets ----------------------------------------------------- DO NOT EDIT THIS LINE ***/ /*** Syntax ====== {p 8 16 2} {cmd: makediagram} [{help using} {it:filename}] {cmd:,} {it:export(filename)} [ {it:replace} {it:graphtype(name)} {it:style(filename)} ] {p_end} {* the new Stata help format of putting detail before generality}{...} {synoptset 20 tabbed}{...} {synopthdr} {synoptline} {synopt:{opt e:xport(filename)}}export the DOT diagram file. {p_end} {synopt:{opt graphtype(name)}}specifies the type of the graph which can be {bf:digraph} (default) or {bf:graph} (i.e. undirected). {p_end} {synopt:{opt replace}}replace the exported DOT file{p_end} {synopt:{opt style(filename)}}appends an external DOT style sheet to the DOT file.{p_end} {synoptline} {p2colreset}{...} Description =========== __makediagram__ generates a [DOT](http://en.wikipedia.org/wiki/Dot) file from a data set that can be rendered to a graphical file using {help diagram} program within Stata. the data set should be prepared as explained in the next section. Variable discription ==================== The data set should have 5 variables named __cluster__ (numeric), __from__ (numeric or string), __to__ (numeric or string), __label__ (string), and __properties__ (string). The numeric variables can have labels which also changes the labels in the DOT file. cluster from to label properties --------- -------- -------- ------- ----------- numeric numeric numeric string string or or or string string string the __cluster__, __label__, and __properties__ can be missing. however, the __from__ and __to__ variables specifies which nodes are connected to one another. in directed graphs, the direction is __"from"__ towards __"to"__. However, in undirected graphs, this direction is of no significance and only shows a connection. the __cluster__ variable defines in which subgraph the connection takes place (see the examples) the __from__ and __to__ variables specify the nodes where the connection begines and ends. the variables can be numeric, e.g. the nodes can be {bf:1 -> 2} or strings such as {bf:A -> B} or {bf:"Node A" -> "Node B"}. If the variables are numeric, their label is automatically used to alter the labels of the DOT graph (see the examples). the __label__ variable simply "labels the connection". this merely specifies the "label" or "value" for the arrow. the label of the connection can also be specified within the __properties__ variable, but due to its common use and importance (_and to make life easier for those who don't wish to learn the DOT language_), it is made available as a separate variable. yet, adding __label="__ _label_ __"__ in the __properties__ variable can change the connection label. Example(s) ================= the [diagram torture test](https://raw.githubusercontent.com/haghish/diagram/master/torture_test.do) includes several examples and example data sets for testing the package. exporting a directed DOT script file from a data set . makediagram using name.dta, export("name.txt") label("diagram's label") exporting undirected DOT script file . makediagram using name.dta, export("name.txt") graphtype(graph) Author ====== __E. F. Haghish__ Center for Medical Biometry and Medical Informatics University of Freiburg, Germany _and_ Department of Mathematics and Computer Science University of Southern Denmark haghish@imbi.uni-freiburg.de [http://www.haghish.com/markdoc](http://www.haghish.com/statistics/stata-blog/reproducible-research/markdoc.php) Package Updates on [Twitter](http://www.twitter.com/Haghish) - - - This help file was dynamically produced by {help markdoc:MarkDoc Literate Programming package} ***/ *cap prog drop makediagram prog define makediagram version 11 syntax [using/] , Export(str) [replace] [GRAPHtype(name)] /// [style(str)] // ------------------------------------------------------------------------- // Make sure the data is .dta; initiate the diagram text file // ========================================================================= if !missing("`using'") { if (!index(lower("`using'"),".dta")) { di as err "specified data is not supported" err 198 } } if "`graphtype'" == "graph" { local source "graph G {" local sign -- } else if "`graphtype'" == "digraph" | missing("`graphtype'") { local source "digraph G {" local sign -> } else { di as err "{bf:graphtype} invalid" err 198 } tempfile tmp tempname knot qui file open `knot' using "`tmp'", write replace file write `knot' "`source'" _n // adding external style // ------------------------------------------------------------------------- if !missing("`style'") { confirm file "`style'" tempname hitch qui file open `hitch' using "`style'", read file read `hitch' line while r(eof)==0 { *local source = `"`macval(source)'"' + `"`macval(line)'"' file write `knot' `"`macval(line)'"' _n file read `hitch' line } } // ------------------------------------------------------------------------- // Loading the specified data set, if specified // ========================================================================= if !missing("`using'") { preserve qui use "`using'", clear } // ------------------------------------------------------------------------- // Testing the data set variables // ========================================================================= // Check if cluster variable exists: // IF cluster variable exists and it is missing, OR IF it does not exist: // ELSE if it exists and not missing: // ------------------------------------------------------------------------- capture confirm variable cluster if _rc == 0 { if missing(cluster) { file close `knot' diagramconnection , tempfile("`tmp'") sign(`sign') file open `knot' using "`tmp'", write append } else { //check if cluster is string cap confirm string variable cluster if _rc == 0 local clusterisstring 1 qui drop if missing(cluster) //drop missing values *sort cluster tempfile master qui save `master' clear qui use `master' //first evaluate when cluster observation is not missing //if cluster is string, the missings come first local current : di cluster[1] while !missing(cluster[1]) { qui keep if cluster == cluster[1] if missing("`clusterisstring'") { local nme : di "`: label (cluster) `=cluster[1]''" // label } if !missing("`clusterisstring'") { if substr(cluster[1], 1,1) == `"""' { local current : di substr(`"`macval(current)'"',2,.) } if substr(cluster[1], -1,1) == `"""' { local current : di substr(`"`macval(current)'"',1,strlen(`"`macval(current)'"')-1) } local nme `"`macval(current)'"' // label //remove white space local current : subinstr local current " " "", all } file write `knot' " subgraph cluster_`current' {" _n if !missing("`nme'") file write `knot' `" label="`nme'";"' _n file close `knot' diagramconnection , tempfile("`tmp'") sign(`sign') indent(" ") file open `knot' using "`tmp'", write append file write `knot' " }" _n qui use `master', clear qui drop if cluster == cluster[1] qui save `master', replace local current : di cluster[1] } *else { * qui drop if missing(cluster) *} //evaluate for observations with missing cluster *qui use "`using'", clear if !missing("`using'") { qui use "`using'", clear } //evaluate arguments when cluster is missing qui keep if missing(cluster) file close `knot' diagramconnection , tempfile("`tmp'") sign(`sign') file open `knot' using "`tmp'", write append } } //if missing cluster variable... else { file close `knot' diagramconnection , tempfile("`tmp'") sign(`sign') file open `knot' using "`tmp'", write append } file close `knot' if !missing("`using'") local use using "`using'" diagramnode `use' , tempfile("`tmp'") file open `knot' using "`tmp'", write append file write `knot' "}" _n file close `knot' copy "`tmp'" "`export'", `replace' if !missing("`using'") restore cap confirm file "`export'" if _rc == 0 { di as txt "{p}({bf:makediagram} created "`"{bf:{browse "`export'"}})"' _n } else display as err "{bf:makediagram} could not produce `export'" _n end * markdoc makediagram.ado, export(sthlp) replace ascii * markdoc makediagram.ado, export(pdf) replace style(stata) linesize(200) *makediagram, export(sth.txt) replace