How to get a graphical model representation with standardized path coefficients?

Posted on
Picture of user. trinewa Joined: 11/30/2009

Hi
Is there any way in OpenMx or R to get a graphical representation of a multivariate common pathways heterogeneity model, with standardized path coefficients? Running the omxGraphviz produces the error message that the model is not a RAM type model.

Replied on Mon, 02/28/2011 - 03:52
Picture of user. tbates Joined: Jul 31, 2009

hi t,
omxGraphviz only works with RAM models.

Because you can call any matrix anything inside your common pathway model, there is no way for omxGraphviz to know what r1c1 in matrix "aSpec" means (to give an example of quasi-arbitrary obscureness ;-).

It is not very hard to write a function that uses whatever conventions you have adopted to convert the model into ".dot" language.

if you know that this describes 4 paths from "aspec1" to "ext" and so forth:

aSpec
ext .5 .4
anx .1 .8

Then you just want to write a function that works its way through the various matrices that contain your path loadings, and output lines like

aspec1 -> ext [value=.5]

It's not trivial, and requires knowledge of paste and suchlike, but is worth learning, and gives you all the diagrammatic goodness you might want.

t

Replied on Fri, 03/04/2011 - 11:02
Picture of user. trinewa Joined: Nov 30, 2009

In reply to by tbates

Hi again
Based on your hints, I was able to get a graphic output of my model, but I had to solve the problem outside R, and the values of the model need to be entered into the .dot syntax manually.
Here's what I did:
1) Downloaded the open source program WinGraphViz from this website: http://www.graphviz.org/
2) Opened the http://graphviz-dev.appspot.com/ website and entered the following .dot syntax, see attached file.
3) Right-clicked on the image of the resulting graph and saved it as a .bmp file

It is not at all elegant, but I got my graphical drawing of the model. Any improvement of this procedure is highly appreciated.

Replied on Sun, 03/06/2011 - 10:22
Picture of user. mdewey Joined: Jan 21, 2011

In reply to by trinewa

Trine
I think you would do better to use R to write out the dot file and then run the dot program on it. You can run dot from within R using system().

I am not familiar with the model you are trying to fit but suppose you wanted to write a diagram which contained the information that you normally get from doing summary(fit)$parameters. You would save that as a dataframe and then work through the columns writing out nodes containing all the names you find in the "row" or "col" columns and then write out the paths using the information in the "row", "col" to place the arc and "name" and "Estimate" columns to label the arc. If you want to look at a primitive example of this (nothing to do with OpenMx) download the source of the latdiag package from CRAN. (Disclaimer: I am the author of latdiag).

Hope that helps.

Replied on Sun, 03/06/2011 - 11:27
Picture of user. tbates Joined: Jul 31, 2009

In reply to by trinewa

You need a function for each model type you create, and you probably need to label all the free parameters in some sensible fashion (I use nameRC i.e., a11 a12 etc...) . As a starter, here's one I wrote for drawing two group Cholesky models

graphViz_Cholesky <- function(model=NA, selDVs=selDVs, dotFilename="Cholesky.dot") {
	# written tim.bates@ed.ac.uk
        # e.g. call
	# graphViz_Cholesky(model,selDVs=selDVs, dotFilename="Cholesky.dot")
	omxGetParameters(model)->parameterKeyList;
	out           = "";
	variableCount = length(selDVs)/2;
	latents       = c();
	for(thisParam in names(parameterKeyList) ) {
		if (grepl("^[ace][0-9][0-9]", thisParam)) { # a c e
			from    = sub('([ace])([0-9])([0-9])'   , '\\1\\3', thisParam, perl=T);  # a c or e
			target  = as.numeric(sub('([ace])([0-9])([0-9])', '\\2', thisParam, perl=T));
			target  = selDVs[as.numeric(target)]
			latents = append(latents, from)
		} else { # means probably
			from   = thisParam;
			target = sub('(^[^0-9]+)([0-9])([0-9])', 'var\\3', thisParam, perl=T) 
		}
		out = paste(out, ";\n", from, " -> ", target, " [label=\"", round(parameterKeyList[thisParam],2), "\"]", sep="")
	}
	preOut= "";
	for(var in selDVs[1:variableCount]) {
	   preOut = paste(preOut, "\n", var, " [shape=box];\n", sep="")
	}
	rankVariables = paste("{rank=same; ", paste(selDVs[1:variableCount], collapse="; "), "};") # {rank=same; religT1; ethnicT1; raceT1 }
	latents = unique(latents)
	grep('a', latents, value=T)
	rankA   = paste("{rank=min; ", paste(grep('a', latents, value=T), collapse="; "), "};") # {rank=min; a1; a2 }
	rankCE  = paste("{rank=max; ", paste(grep('[ce]', latents, value=T), collapse="; "), "};") # {rank=min; c1; e1; e2 }
	digraph = paste("digraph G {\nsplines=\"FALSE\";\n", preOut, out, rankVariables, rankA, rankCE, "\n}", sep="");
	# cat(digraph);
	# return (out)
	if(!is.na(dotFilename)){
		cat(digraph, file = dotFilename)
		system(paste("open", dotFilename));
		# return(invisible(cat(digraph)))
	} else {
		return (cat(digraph));
	}
}

PS: You mention downloading a graphviz app, but then use the online creator: The desktop app is probably more useful.