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

6 replies [Last post]
trinewa's picture
Offline
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.

tbates's picture
Offline
Joined: 07/31/2009
hi t, omxGraphviz only works

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

trinewa's picture
Offline
Joined: 11/30/2009
Hi again Based on your hints,

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.

AttachmentSize
GraphViz_MvHetComPMod.txt 1.7 KB
tbates's picture
Offline
Joined: 07/31/2009
You need a function for each

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.

trinewa's picture
Offline
Joined: 11/30/2009
Thank you all for valuable

Thank you all for valuable advice!
Trine

mspiegel's picture
Offline
Joined: 07/31/2009
If all your free parameters

If all your free parameters have non-NA labels, you could use:

modelOut <- mxRun(model)
parameterValues <- omxGetParameters(modelOut)
model <- omxSetParameters(model, names(parameterValues), values = parameterValues)

mdewey's picture
Offline
Joined: 01/21/2011
Trine I think you would do

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.