thomasp85 / ggraph

Grammar of Graph Graphics
https://ggraph.data-imaginist.com
Other
1.06k stars 111 forks source link

Plot networks from lavaan? #36

Closed Deleetdk closed 6 years ago

Deleetdk commented 7 years ago

It would be neat if this package could implement the functionality that semPlot has.

http://sachaepskamp.com/semPlot/examples#Lavaan

It can extract the edge list/connection matrix from lavaan or lm class objects and automatically plot them. The results are not very pretty and hard to deal with because it's based on base plot. So I'm looking for some ggplot2 based solution for plotting SEMs. Right now I manually draw SEMs using e.g. draw.io or Google Draw. This is quite time-consuming, especially when updating numbers on paths.

I managed to convert that into an igraph object and plot it.

library(pacman)
p_load(lavaan, magrittr, igraph)

#fit simple reg
fit = sem("Sepal.Length ~ Sepal.Width + Petal.Length", data = iris)
fit_params = fit %>% parameterestimates()
fit_betas = fit_params %>% dplyr::filter(op == "~") %>% `[`("est") %>% unlist

#adj mats
beta_mat = fit@Model@GLIST$beta
log_mat = (fit@Model@GLIST$beta != 0)
adj_mat = log_mat %>% as.integer %>% matrix(nrow = nrow(fit@Model@GLIST$beta), byrow = T)
rownames(adj_mat) = colnames(adj_mat) = fit@Data@ov.names[[1]]
betas = beta_mat[log_mat]

#to igraph
adj_mat %>% 
  graph_from_adjacency_matrix() %>% 
  plot.igraph(edge.label = betas %>% round(2)
              )

#alternative approach
fit_params %>% 
  dplyr::filter(op == "~") %>% 
  `[`(c("rhs", "lhs")) %>% 
  as.matrix %>% 
  graph_from_edgelist %>% 
  plot.igraph(edge.label = fit_betas %>% round(2))

I was not able to get further because of #34.

Deleetdk commented 7 years ago

Just to let others know, I'm working on some code that can seamlessly input a lavaan fit object and then output an igraphclass object ready for plotting with ggraph, including with the correct directional links and their coefficients.

I've never worked with network analysis like this before, so there is some learning involved on my part. So far, have the adjacency matrix worked out. Need to add the path coefficients, but I think I know how to do that from reading this igraph tutorial.

The difficult part after that is having it automatically select a layout that's mostly acceptable. It's my understanding that there's a bunch of algos for this already, but they often produce not quite good results. Maybe there's some theorem that one cannot make an algo that consistently produces decent outcomes, but I'm inclined to try (and maybe it is futile).

DominiqueMakowski commented 5 years ago

@Deleetdk Hey, any advances on this useful feature? Thanks