介绍
DiagrammeR 依赖于图形描述语言 Graphviz,可以通过 R 包 igraph 和 visNetwork 访问。DiagrammeR 通过将有效的图规范以 DOT 语言的形式传递给 grViz() 函数来输出图。
加载R包
采用DiagrammeR
R包,它提供了以下函数:
-
使用
create_graph()
和render_graph()
在节点和边的列表上。 -
创建一个有效的
DOT
语言图规范,并将此作为字符串传递给函数grViz()
。 -
创建一个有效的图规范,并将此作为字符串或 .mmd 文件引用传递给函数 mermaid()。
{r,
knitr::opts_chunk$set(message = FALSE, warning = FALSE)
if (!require("pacman")) {
install.packages("pacman")
}
pacman::p_load(here,
tidyverse,
DiagrammeR,
DiagrammeRsvg,
rsvg,
xml2,
plotly)
rm(list = ls())
options(stringsAsFactors = F)
options(future.globals.maxSize = 10000 * 1024^2)
create_graph创建图
简单的图可以通过在节点和边的数据框列表上使用 create_graph()
方法来创建。这种方法对于绘制对象之间的简单关系非常方便。
{r}
# 定义图边和节点
# 1 == "Photosynthesis"
# 2 == "Aerobic respiration"
# 3 == "Solar energy"
edges <- create_edge_df(from = c(1, 2, 3),
to = c(2, 1, 1),
label = c("Oxygen \n Glucose", "Carbon dioxide \n Water", NA),
color = "black")
nodes <- create_node_df(n = 3,
label = c("Photosynthesis", "Aerobic \n respiration", "Solar \n energy"),
type = "lower",
style = "filled",
fillcolor = c("darkseagreen", "mistyrose", "gold"),
fontcolor = "black",
shape = "circle",
fixedsize = T)
# 创建图
simple_graph <- create_graph(nodes_df = nodes, edges_df = edges)
# 渲染图
render_graph(simple_graph)
# 导出图
# export_graph(simple_graph,
# file_name = here("figures", "dv-using_diagrammer-simple_flowchart.svg"),
# file_type = "svg")
如果您想创建更复杂的流程图,这种方法存在一些限制。
- 边必须使用到和从的数值向量进行编码。
- 没有简单的方法来指定节点位置(将太阳能显示为顶部节点是有意义的)。
- 没有简单的方法来指定边标签的位置。
- 如果节点标签太长,图形输出会被修剪。
grVis创建流程图
创建流程图
{r}
simple_flowchart <- grViz(
"digraph {
graph[layout = dot, rankdir = LR] # Set node direction
node[shape = circle, style = filled] # Set global node attributes
a[label = 'Photosynthesis', fillcolor = 'darkseagreen']
b[label = 'Aerobic \nrespiration', fillcolor = 'mistyrose']
c[label = 'Solar \nenergy', fillcolor = 'gold']
edge[color = black, fontsize = 8] # Set global edge attributes
a -> b[label = 'Oxygen \nGlucose']
a -> b[style = 'invis']
a -> b[style = 'invis']
b -> a[label = 'Carbon dioxide \n Water']
b -> a[style = 'invis']
b -> a[style = 'invis']
c -> a[label = ' ']
}"
)
simple_flowchart
# # Export graph as an svg -------------------------------------------------------
# simple_flowchart %>%
# export_svg %>%
# charToRaw %>%
# rsvg_svg(here("figures", "dv-using_diagrammer-simple_grvis.svg"))
- 为节点和边设置全局属性,并在需要时使用局部属性手动覆盖个别节点或边。
- 按照这里推荐的方法,创建额外的不可见边层以增加特定节点之间的箭头曲率。
- 创建一个带有空字符串的边标签,以增加特定边的长度。
grVis创建复杂流程图
- 机器学习流程图
{r}
# Create a flow chart to describe my ML workflow -------------------------------
ml_workflow <- grViz(
"digraph {
graph[layout = dot]
node[shape = rectangle, style = filled, fillcolor = 'blanchedalmond']
data_source_1[label = 'Data \n warehouse', shape = cylinder, fillcolor = 'azure']
data_source_2[label = 'Survey.csv', fillcolor = 'aliceblue']
data_source_3[label = 'External data \n API', shape = cylinder, fillcolor = 'azure']
process_1[label = 'Data cleaning \n and joining']
process_2[label = 'Feature selection']
process_3[label = 'Split train \n and test dataset']
process_4[label = 'Cross-validation']
process_5[label = 'Test different \n ML algorithms']
process_6[label = 'Select optimal \n ML model']
file_1[label = 'Clean data', fillcolor = 'aliceblue']
file_2[label = 'Training data', fillcolor = 'aliceblue']
file_3[label = 'Test data', fillcolor = 'aliceblue']
product_1[label = 'Optimal \n ML model', shape = 'ellipse', fillcolor = 'lightsalmon']
edge[color = black, fontsize = 12]
data_source_1 -> process_1
data_source_2 -> process_1
data_source_3 -> process_1
process_1 -> file_1
file_1 -> process_2
process_2 -> process_3
process_3 -> file_2
process_3 -> file_3
file_2 -> process_4
process_4 -> process_5
process_5 -> process_4
process_5 -> file_3
file_3 -> process_6
process_6 -> product_1
product_1 -> file_2[label = ' Constantly monitor \n for ML model drift',
style = 'dashed', penwidth = 2, weight = 2,
color = 'firebrick', fontcolor = 'firebrick']
}"
)
ml_workflow
# # Export graph as an svg -------------------------------------------------------
# ml_workflow %>%
# export_svg %>%
# charToRaw %>%
# rsvg_svg(here("figures", "dv-using_diagrammer-ml_workflow.svg"))
- 临床试验图
{r}
# Create flow chart with flexible parameter inputs -----------------------------
set.seed(111)
a <- 200 # Total patients
b <- sample(1:60, 1) # Excluded patients
c <- 200 - b # Randomised patients
d <- ceiling(c/2) # Assigned treatment A
e <- c - d # Assigned treatment B
# Store parameters inside a list
flow_chart_data <- list(a, b, c, d, e)
# Create grVis() graph
simple_trial <- grViz(
"digraph {
graph[layout = dot]
node[shape = rectangle, style = filled, margin = 0.2, fillcolor = 'aliceblue']
a[label = '@@1']
b[label = '@@2', fillcolor = 'mistyrose']
c[label = '@@3']
d[label = '@@4']
e[label = '@@5']
edge[color = black]
a -> b[style = 'dashed']
a -> c[weight = 2] # Weighs this edge more heavily so it is centrally placed
c -> d
c -> e
}
[1]: paste0('Patients screened (n = ', flow_chart_data[[1]], ')')
[2]: paste0('Patients excluded (n = ', flow_chart_data[[2]], ')')
[3]: paste0('Patients randomised (n = ', flow_chart_data[[3]], ')')
[4]: paste0(' Patients assigned Treatment A (n = ', flow_chart_data[[4]], ')')
[5]: paste0(' Patients assigned Treatment B (n = ', flow_chart_data[[5]], ')')
"
)
simple_trial
# # Export graph as an svg -------------------------------------------------------
# simple_trial %>%
# export_svg %>%
# charToRaw %>%
# rsvg_svg(here("figures", "dv-using_diagrammer-flowchart_clinical_single.svg"))
- 多研究中心临床试验图
{r}
# Create flow chart with flexible parameter inputs -----------------------------
set.seed(111)
a <- 200
b <- sample(1:60, 1)
c <- 200 - b
d <- ceiling(c/2)
e <- c - d
set.seed(222)
f <- 125
g <- sample(1:45, 1)
h <- 125 - b
i <- ceiling(h/2)
j <- h - i
# Store subgroup parameters in separate lists
hospital_a <- list(a, b, c, d, e)
hospital_b <- list(f, g, h, i, j)
# Create grVis() graph
multi_trial <- grViz(
"digraph {
graph[layout = 'dot', rankdir = TB]
node[shape = rectangle, style = filled, margin = 0.2, fillcolor = 'azure']
subgraph cluster_a {
graph[rankdir = TB, label = 'Hospital A',
fontsize = 18, shape = rectangle, style = dashed]
a[label = '@@1']
b[label = '@@2', fillcolor = 'mistyrose']
c[label = '@@3']
d[label = '@@4', fillcolor = 'aliceblue']
e[label = '@@5', fillcolor = 'aliceblue']
}
subgraph cluster_b {
graph[rankdir = TB, label = 'Hospital B',
fontsize = 18, shape = rectangle, style = dashed]
f[label = '@@6']
g[label = '@@7', fillcolor = 'mistyrose']
h[label = '@@8']
i[label = '@@9', fillcolor = 'aliceblue']
j[label = '@@10', fillcolor = 'aliceblue']
}
edge[color = black]
a -> b[style = 'dashed']
a -> c[weight = 2]
c -> d
c -> e
f -> g[style = 'dashed']
f -> h[weight = 2]
h -> i
h -> j
}
[1]: paste0('Patients screened (n = ', hospital_a[[1]], ')')
[2]: paste0('Patients excluded (n = ', hospital_a[[2]], ')')
[3]: paste0('Patients randomised (n = ', hospital_a[[3]], ')')
[4]: paste0(' Patients assigned Treatment A (n = ', hospital_a[[4]], ')')
[5]: paste0(' Patients assigned Treatment B (n = ', hospital_a[[5]], ')')
[6]: paste0('Patients screened (n = ', hospital_b[[1]], ')')
[7]: paste0('Patients excluded (n = ', hospital_b[[2]], ')')
[8]: paste0('Patients randomised (n = ', hospital_b[[3]], ')')
[9]: paste0(' Patients assigned Treatment A (n = ', hospital_b[[4]], ')')
[10]: paste0(' Patients assigned Treatment B (n = ', hospital_b[[5]], ')')
"
)
multi_trial
# # Export graph as an svg -------------------------------------------------------
# multi_trial %>%
# export_svg %>%
# charToRaw %>%
# rsvg_svg(here("figures", "dv-using_diagrammer-flowchart_clinical_multiple.svg"))