绘制R中的多个/并行中介模型的示意图

eqzww0vc  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(235)

我想绘制一个R中的并行中介模型的发布就绪图。
我修改了这里提供的Diagramer + Graphviz代码https://stackoverflow.com/questions/46465752/drawing-simple-mediation-diagram-in-r,但是我似乎没有得到预期的输出。我想我在 rank 参数上做错了什么。
我的目标是把预测因子和结果放在底部,把所有三个调节因子放在上面的一条垂直线上。
下面的代码几乎可以得到它,但是把两个中介放在下面而不是上面。如果从xx到yy的箭头至少落在盒子的中间,这也可以工作。

med_data <-
  data.frame(
    lab_x   = "XXXXXX",
    lab_m1   = "MMMMMM 1",
    lab_m2   = "MMMMMM 2",
    lab_m3   = "MMMMMM 3",
    lab_y   = "YYYYYYY",
    coef_xm1 = "0.11*",
    coef_m1y = "0.11*",
    coef_xm2 = "0.22*",
    coef_m2y = "0.22*",
    coef_xm3 = "0.33*",
    coef_m3y = "0.33*",
    coef_xy = "0.66*"
  )

med_diagram <- function(data, height = .75, width = 2, 
                        graph_label = NA, node_text_size = 12, 
                        edge_text_size = 12, color = "black", 
                        ranksep = .2, minlen = 3){
  
  require(glue)
  require(DiagrammeR)
  
  data$height  <- height   # node height
  data$width   <- width    # node width
  data$color   <- color    # node + edge border color
  data$ranksep <- ranksep  # separation btwn mediator row and x->y row
  data$minlen  <- minlen   # minimum edge length
  
  data$node_text_size  <- node_text_size
  data$edge_text_size  <- edge_text_size
  
  data$graph_label <- ifelse(is.na(graph_label), "", 
                             paste0("label = '", 
                                    graph_label, "'"))
  
  diagram_out <- glue::glue_data(data,
                                 "digraph flowchart {
      fontname = Helvetica
      <<graph_label>>
      graph [ranksep = <<ranksep>>]

      # node definitions with substituted label text
      node [fontname = Helvetica, shape = rectangle, fixedsize = TRUE, 
      width = <<width>>, height = <<height>>, fontsize = <<node_text_size>>, 
      color = <<color>>]        
        mm1 [label = '<<lab_m1>>']
        xx [label = '<<lab_x>>']
        yy [label = '<<lab_y>>']
        mm2 [label = '<<lab_m2>>']
        mm3 [label = '<<lab_m3>>']

      # edge definitions with the node IDs
      edge [minlen = <<minlen>>, fontname = Helvetica, 
      fontsize = <<edge_text_size>>, color = <<color>>]
        xx -> yy [label = '<<coef_xy>>'];
        mm1 -> yy [label = '<<coef_m1y>>'];
        xx -> mm1 [label = '<<coef_xm1>>'];
        mm2 -> yy [label = '<<coef_m2y>>'];
        xx -> mm2 [label = '<<coef_xm2>>'];
        mm3 -> yy [label = '<<coef_m3y>>'];
        xx -> mm3 [label = '<<coef_xm3>>'];
        
      rankdir = LR;
      { rank = same; mm1; mm2; mm3 }
      
      }

      ", .open = "<<", .close = ">>")  
  
  
  DiagrammeR::grViz(diagram_out)  
}

med_diagram(med_data)

输出,调解模式1:

我尝试的第二个版本,导致所有的中介体都在一条水平线上,而不是一条垂直线上:

med_data <-
  data.frame(
    lab_x   = "XXXXXX",
    lab_m1   = "MMMMMM 1",
    lab_m2   = "MMMMMM 2",
    lab_m3   = "MMMMMM 3",
    lab_y   = "YYYYYYY",
    coef_xm1 = "0.11*",
    coef_m1y = "0.11*",
    coef_xm2 = "0.22*",
    coef_m2y = "0.22*",
    coef_xm3 = "0.33*",
    coef_m3y = "0.33*",
    coef_xy = "0.66* (.16)"
  )

med_diagram <- function(data, height = .75, width = 2, 
                        graph_label = NA, node_text_size = 12, 
                        edge_text_size = 12, color = "black", 
                        ranksep = .2, minlen = 3){
  
  require(glue)
  require(DiagrammeR)
  
  data$height  <- height   # node height
  data$width   <- width    # node width
  data$color   <- color    # node + edge border color
  data$ranksep <- ranksep  # separation btwn mediator row and x->y row
  data$minlen  <- minlen   # minimum edge length
  
  data$node_text_size  <- node_text_size
  data$edge_text_size  <- edge_text_size
  
  data$graph_label <- ifelse(is.na(graph_label), "", 
                             paste0("label = '", 
                                    graph_label, "'"))
  
  diagram_out <- glue::glue_data(data,
                                 "digraph flowchart {
      fontname = Helvetica
      <<graph_label>>
      graph [ranksep = <<ranksep>>]

      # node definitions with substituted label text
      node [fontname = Helvetica, shape = rectangle, fixedsize = TRUE, 
      width = <<width>>, height = <<height>>, fontsize = <<node_text_size>>, 
      color = <<color>>]        
        mm1 [label = '<<lab_m1>>']
        xx [label = '<<lab_x>>']
        yy [label = '<<lab_y>>']
        mm2 [label = '<<lab_m2>>']
        mm3 [label = '<<lab_m3>>']

      # edge definitions with the node IDs
      edge [minlen = <<minlen>>, fontname = Helvetica, 
      fontsize = <<edge_text_size>>, color = <<color>>]
        xx -> yy [label = '<<coef_xy>>'];
        mm1 -> yy [label = '<<coef_m1y>>'];
        xx -> mm1 [label = '<<coef_xm1>>'];
        mm2 -> yy [label = '<<coef_m2y>>'];
        xx -> mm2 [label = '<<coef_xm2>>'];
        mm3 -> yy [label = '<<coef_m3y>>'];
        xx -> mm3 [label = '<<coef_xm3>>'];
        

      { rank = max; xx; yy}
      }

      ", .open = "<<", .close = ">>")  
  
  
  DiagrammeR::grViz(diagram_out)  
}

med_diagram(med_data)

输出,调解模式2:

帮助和一点输入的排名部分将是惊人的或替代包解决这个问题。
更新:以下是示例图片:Example Model

9gm1akwq

9gm1akwq1#

最佳排名参考:https://www.graphviz.org/pdf/dotguide.pdf(特别是第7页和第15页)和https://www.graphviz.org/docs/attrs/rank/
总而言之,这不是Graphviz的强项。我不使用Diagramer,但下面的Graphviz代码可能很容易翻译。

digraph N{
  splines=false // straight line edges
  rankdir=TB    // same as default
  nodesep=1.2
  ranksep=.2
  node [shape=rect]
 
  // set these nodes one per rank
  mm1 -> mm2 [style=invis]
  mm2 -> mm3 [style=invis]

  xxxx -> mm1:w
  xxxx -> mm2:w
  xxxx -> mm3:w
  mm1:e -> yyyy
  mm2:e -> yyyy
  mm3:e -> yyyy
  {
   rank=source  //  these nodes on the top. use rank=sink if you want these nodes on bottom
   // bogus node is needed to keep left-right symmetry, not sure why
   bogus [style=invis shape=plain]
   xxxx -> yyyy
   xxxx -> bogus [style=invis]
   bogus -> yyyy [style=invis]
  }
}

给予:

相关问题