在R中绘制简单的中介图

bla*_*zej 6 diagram r ggplot2

是否有一种(最好是简单易懂的)方式来绘制带有R中中介系数的简单路径图?

我一直在寻找DiagrammeR打包的方法,但是这看起来像是一种矫kill过正(老实说,我未能弄清楚如何绘制剧情)。

我知道的其他选项是DiaInkscape,但这些选项需要手动定位,连接路径等。

mediation包中有一个plot选项,但它会绘制自举的CI,而我想要实现的是一条具有如下所示系数的简单路径:

来源:http://my.ilstu.edu/~jhkahn/medmod.html

bla*_*zej 7

虽然@baptiste解决方案也可能有效,但我一直在寻找一种可发布的格式。

函数plotmatfromlibrary(diagram)是让我最接近我的示例的函数:

路径图

对于可重现的示例,请使用:

library(diagram)
data <- c(0, "'.47*'", 0,
          0, 0, 0, 
          "'.36*'", "'.33* (.16)'", 0)
M<- matrix (nrow=3, ncol=3, byrow = TRUE, data=data)
plot<- plotmat (M, pos=c(1,2), 
                name= c( "Math self-efficacy","Math ability", "Interest in the math major"), 
                box.type = "rect", box.size = 0.12, box.prop=0.5,  curve=0)
Run Code Online (Sandbox Code Playgroud)


Oma*_*sow 7

这是使用 TikZ 构建的中介图的两个版本DiagrammeR和第三个版本。每个都有优点和缺点:

  • 图解 + Graphviz:

    • 优点:使用提供的功能可以轻松创建图表,有很多选项可以调整节点的设计。
    • 缺点:调整边缘文本的选项很少,输出是一个 htmlwidget 对象,可以打印为 pdf,但在特定情况下(例如在 for 循环内)可能需要转换。
  • 蒂克Z

    • 优点:高度可定制,包括边缘文本;使用提供的功能轻松生成图表
    • 缺点:如果你需要 HTML 输出,它是为 LaTeX 设计的;语法可能会令人困惑
  • DiametermeR 原生语法(仅为了完整性而提供)

    • R优点:代码非常易于用户阅读和编辑
    • 缺点:调整边缘文本的明显方法更少

我使用一个函数编写了第一个和第二个示例,该函数med_diagram使用该glue包来组装相关的 graphviz 或 TikZ 代码。该函数需要一个 data.frame,其中一行包含相关标签和系数的列。对于DiagrammeR 特定的函数,还有调整设计的各种元素的参数。

制图师 + Graphviz

med_data <-
  data.frame(
    lab_x   = "Math\\nAbility",
    lab_m   = "Math\\nself-efficacy",
    lab_y   = "Interest in the\\nmath major",
    coef_xm = "0.47*",
    coef_my = "0.36*",
    coef_xy = "0.33* (.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>>]        
        mm [label = '<<lab_m>>']
        xx [label = '<<lab_x>>']
        yy [label = '<<lab_y>>']

      # edge definitions with the node IDs
      edge [minlen = <<minlen>>, fontname = Helvetica, fontsize = <<edge_text_size>>, color = <<color>>]
        mm -> yy [label = '<<coef_my>>'];
        xx -> mm [label = '<<coef_xm>>'];
        xx -> yy [label = '<<coef_xy>>'];
      
      { rank = same; mm }
      { rank = same; xx; yy }
      
      }

      ", .open = "<<", .close = ">>")  


DiagrammeR::grViz(diagram_out)  
}

med_diagram(med_data)
Run Code Online (Sandbox Code Playgroud)

函数生成的中介图

蒂克Z

TikZ 和 PGF 需要在序言中作为 LaTeX 包加载。下面的示例代码包括这些包和一些附加命令,例如,为图中使用的“mynode”设置全局规范。我收到一条警告,要求将其包含\pgfplotsset{compat=1.17}在序言中,但对其他人来说可能没有必要。请注意,此代码基于此处提供的示例构建: https: //tex.stackexchange.com/a/225940/34597

---
title: "Sample Rmd"
author: "Your name here"
output: pdf_document
header-includes:
  - \usepackage{tikz}
  - \usepackage{pgfplots}
  - \pgfplotsset{compat=1.17}
  - \tikzset{mynode/.style={draw,text width=1in,align=center} }
  - \usetikzlibrary{positioning}
---

```{r, load_packages, include = FALSE}
library(glue)
```
  
```{r, load_function}
med_diagram_tikz <- function(data) {
  glue::glue_data(data, 
"
\\begin{figure}
\\begin{center}
\\begin{tikzpicture}[font=\\sffamily]
    \\node[mynode] (m){<<lab_m>>};
    \\node[mynode,below left=of m](x) {<<lab_x>>};
    \\node[mynode,below right=of m](y) {<<lab_y>>};
    \\draw[-latex] (x.north) -- node[auto] {<<coef_xm>>} (m.west);
    \\draw[-latex] (m.east) -- node[auto] {<<coef_my>>} (y.north);
    \\draw[-latex] (x.east) -- node[below=2mm, align=center] {<<coef_xy>>} (y.west);
\\end{tikzpicture}
\\end{center}
\\end{figure}
", 
.open = "<<", .close = ">>"
)
}
```
  
  
```{r create_diagram, echo = FALSE, results = 'asis'}
med_data <-
  data.frame(
    lab_x   = "Math\\\\Ability",
    lab_m   = "Math\\\\self-efficacy",
    lab_y   = "Interest in the\\\\math major",
    coef_xm = ".47*",
    coef_my = ".36*",
    coef_xy = "0.33* (.16)"
  )

tikz_diagram_out <- med_diagram_tikz(med_data)

# requires chunk header to be set to results = 'asis'
cat("\n", tikz_diagram_out, "\n")

```
Run Code Online (Sandbox Code Playgroud)

TikZ 绘制的中介图

制图师本机语法

中介图的第三个版本使用的语法更容易被R用户理解,但我不喜欢边缘标签文本的放置方式很奇怪(因此有上面的两个替代版本)。

library(DiagrammeR)

# Create a node data frame (ndf)
ndf <- create_node_df(
  n         = 3,
  label     = c( "Math\nself-efficacy","Math\nability", "Interest in\nthe math major"),
  shape     = rep("rectangle", 3),
  style     = "empty",
  fontsize  = 6,
  fixedsize = TRUE,
  height    = .5,
  width     = .75,
  color     = "gray80",
  x         = c(1, 2, 3),
  y         = c(1, 2, 1)
)

# Create an edge data frame (edf)
edf <- create_edge_df(
  from     = c(1, 1, 2),
  to       = c(2, 3, 3),
  label    = c(".47*", ".33* (.16)", ".36*"),
  fontsize = 6,
  minlen   = 1,
  color    = "gray80",
  )

# Create a graph with the ndf and edf
graph <- create_graph(
  nodes_df = ndf,
  edges_df = edf
  )

graph %>%
  render_graph()
Run Code Online (Sandbox Code Playgroud)

显示边缘标签文本未正确排列的示例中介图


use*_*seR 5

您可以使用“psych”包来测试您的调节/调解,它也会为您提供一个情节。

mediate(Output ~ Independent1 + (Mediator), data =mydata)
Run Code Online (Sandbox Code Playgroud)