• R统计绘图-变量分组相关性网络图(igraph)


    一、数据准备

    数据是21个土壤样本的环境因子,细菌和真菌丰度数据。

    1. library(tidyverse)
    2. library(igraph)
    3. library(psych)
    4. ### 1.1 观测-变量数据表
    5. data<- read.csv("data.csv",header = TRUE,
    6. row.names = 1,
    7. check.names=FALSE,
    8. comment.char = "")
    9. head(data)
    10. ​
    11. ### 1.2 变量分类表
    12. type = read.csv("type.csv",header = TRUE,check.names = FALSE)
    13. type # 变量分类信息
    14. ​

    图1|观测-变量数据表。行为观测样本,列为变量。

    图2|变量分类表。node为变量名,type为变量分类。

    二、确定相关性关系

    2.1 计算相关性系数

    psych包的corr.test()计算相关性系数、显著性检验和p值校正。

    1. ### 2.1 计算相关性系数,建议使用spearman系数。
    2. cor <- corr.test(data, use = "pairwise",method="spearman",adjust="holm", alpha=.05,ci=FALSE) # ci=FALSE,不进行置信区间计算,数据量较大时,可以加快计算速度。
    3. cor.r <- data.frame(cor$r) # 提取R值
    4. cor.p <- data.frame(cor$p) # 提取p值
    5. colnames(cor.r) = rownames(cor.r)
    6. colnames(cor.p) = rownames(cor.p) # 变量名称中存在特殊字符,为了防止矩阵行名与列名不一致,必须运行此代码。
    7. write.csv(cor.r,"cor.r.csv",quote = FALSE,col.names = NA,row.names = TRUE) # 保存结果到本地
    8. write.csv(cor.p,"cor.p.csv",quote = FALSE,col.names = NA,row.names = TRUE)
    9. knitr::kable(
    10. head(cor.r),
    11. caption = "cor.r"
    12. )
    13. head(cor.p)

    图3|相关性p值矩阵。

    2.2 确定相关性关系

    1. ### 2.2 确定相关性关系 保留p<=0.05且abs(r)>=0.6的变量间相关关系
    2. #cor.r[abs(cor.r) < 0.6 | cor.p > 0.05] = 0
    3. #cor.r = as.matrix(cor.r)
    4. #g = graph_from_adjacency_matrix(cor.r,mode = "undirected",weighted = TRUE,diag = FALSE)
    5. #### 将数据转换为long format进行过滤,后面绘制网络图需要节点和链接数据,在这一步可以完成格式整理
    6. cor.r$node1 = rownames(cor.r)
    7. cor.p$node1 = rownames(cor.p)
    8. r = cor.r %>%
    9. gather(key = "node2", value = "r", -node1) %>%
    10. data.frame()
    11. p = cor.p %>%
    12. gather(key = "node2", value = "p", -node1) %>%
    13. data.frame()
    14. head(r)
    15. head(p)
    16. #### 将r和p值合并为一个数据表
    17. cor.data <- merge(r,p,by=c("node1","node2"))
    18. cor.data
    19. #### 保留p<=0.05且abs(r)>=0.6的变量间相关关系,并添加网络属性
    20. cor.data <- cor.data %>%
    21. filter(abs(r) >= 0.6, p <= 0.05, node1 != node2) %>%
    22. mutate(
    23. linetype = ifelse(r > 0,"positive","negative"), # 设置链接线属性,可用于设置线型和颜色。
    24. linesize = abs(r) # 设置链接线宽度。
    25. ) # 此输出仍有重复链接,后面需进一步去除。
    26. head(cor.data)

    图4|未删除重复链接前的链接属性表,cor.data。

    三、构建网络图结构数据

    3.1 网络图节点属性整理

    此步构建网络之后,还需要将网络图转换为简单图,去除重复链接。

    1. ### 3.1 网络图节点属性整理
    2. #### 计算每个节点具有的链接数
    3. c(as.character(cor.data$node1),as.character(cor.data$node2)) %>%
    4. as_tibble() %>%
    5. group_by(value) %>%
    6. summarize(n=n()) -> vertices
    7. colnames(vertices) <- c("node", "n")
    8. head(vertices)
    9. #### 添加变量分类属性
    10. vertices %>%
    11. select(-n) %>% # 因为此处的n不准确,所以先删除。
    12. left_join(type,by="node") -> vertices
    13. #### 网络图中节点会按照节点属性文件的顺序依次绘制,为了使同类型变量位置靠近,按照节点属性对节点进行排序。
    14. vertices$type = factor(vertices$type,levels = unique(vertices$type))
    15. vertices = arrange(vertices,type)
    16. write.csv(vertices,"vertices.csv",quote = FALSE,col.names = NA,row.names = FALSE)
    17. head(vertices)

    图5|节点属性表,vertices。

    3.2 构建graph结构数据

    1. ### 3.2 构建graph结构数据
    2. g <- graph_from_data_frame(cor.data, vertices = vertices, directed = FALSE )
    3. g
    4. vcount(g) # 节点数目:82
    5. ecount(g) # 链接数:297
    6. #get.vertex.attribute(g) # 查看graph中包含的节点属性
    7. #get.edge.attribute(g) # 查看graph中包含的链接属性

    图6|未删除重复链接前的graph,g。

    3.3 简单图

    1. ### 3.3 简单图
    2. is.simple(g) # 非简单图,链接数会偏高,所以需要转换为简单图。
    3. E(g)$weight <- 1
    4. g <- igraph::simplify(g,
    5. remove.multiple = TRUE,
    6. remove.loops = TRUE,
    7. edge.attr.comb = "first")
    8. #g <- delete.vertices(g,which(degree(g) == 0)) # 删除孤立点
    9. is.simple(g)
    10. E(g)$weight <- 1
    11. is.weighted(g)
    12. vcount(g) # 节点数目:21
    13. ecount(g) # 链接数:33

    3.4 计算节点链接数

    1. ### 3.4 计算节点链接数
    2. V(g)$degree <- degree(g)
    3. #vertex.attributes(g)
    4. #edge.attributes(g)
    5. g

    图7|删除重复链接后的graph,g。

    3.5 保存graph数据到本地

    1. ### 3.5 graph保存到本地
    2. write.graph(g,file = "all.gml",format="gml") # 直接保存graph结构,gml能保存的graph信息最多。
    3. net.data <- igraph::as_data_frame(g, what = "both")$edges # 提取链接属性
    4. write.csv(net.data,"net.data.csv",quote = FALSE,col.names = NA,row.names = FALSE) # 保存结果到本地。
    5. head(net.data)
    6. vertices <- igraph::as_data_frame(g, what = "both")$vertices # 提取节点属性
    7. write.csv(vertices,"vertices.csv",quote = FALSE,col.names = NA,row.names = FALSE)
    8. head(vertices) # 直接读入之前保存的链接和节点属性文件,之后可直接生成graph或用于其他绘图软件绘图。

    图8|无重复链接属性表,net.data。

    图9|添加degree的新节点属性表,vertices。

    四、绘制分组网络图

    图属性:1) 节点根据分类属性填充颜色和背景色;2) 节点大小按degree设置;3) 链接线根据正负相关性设置颜色;4) 链接线宽度根据abs(r)设置。

    绘图前先确定网络图中的节点位置,即计算每个节点的(x,y)坐标,igraph包中有多个图布局计算函数,可根据不同的算法计算出网络图中的节点坐标位置。可以多尝试几种布局方式,找到最适合自己数据的布局。

    图10|网络图布局方式。来自《R语言数据可视化之美》。

    4.1 设置网络图布局

    1. ### 4.1 准备网络图布局数据
    2. #?layout_in_circle # 帮助信息中,有其它布局函数。
    3. layout1 <- layout_in_circle(g) # 径向布局适合节点较少的数据。
    4. layout2 <- layout_with_fr(g) # fr布局。
    5. layout3 <- layout_on_grid(g) # grid布局。
    6. head(layout1)

    4.2 设置绘图颜色

    1. ### 4.2 设置绘图颜色
    2. #?rgb() # 可以将RGB值转换为16进制颜色名称。
    3. #### 设置节点与分组背景色
    4. color <- c(rgb(65,179,194,maxColorValue = 255),
    5. rgb(255,255,0,maxColorValue = 255),
    6. rgb(201,216,197,maxColorValue = 255))
    7. names(color) <- unique(V(g)$type) # 将颜色以节点分类属性命名
    8. V(g)$point.col <- color[match(V(g)$type,names(color))] # 设置节点颜色。
    9. #names(color2) <- unique(V(g)$type) # 如果想要节点颜色与背景颜色不一致,则可以为节点单独设置一个颜色集。
    10. #V(g)$point.col <- color2[match(V(g)$type,names(color2))]
    11. #### 边颜色按照相关性正负设置
    12. #E(g)$color <- ifelse(E(g)$linetype == "positive",rgb(255,215,0,maxColorValue = 255),"gray50")
    13. E(g)$color <- ifelse(E(g)$linetype == "positive","red",rgb(0,147,0,maxColorValue = 255))

    图11|graph绘图布局,layout1。

    4.3 径向布局网络图

    与其他布局相比,径向网络图比较适合节点较少的数据。

    1. ### 4.3 绘制径向布局网络图
    2. pdf("network_group_circle.pdf",family = "Times",width = 10,height = 12)
    3. par(mar=c(5,2,1,2))
    4. plot.igraph(g, layout=layout1,#更多参数设置信息?plot.igraph查看。
    5. ##节点颜色设置参数##
    6. vertex.color=V(g)$point.col,
    7. vertex.frame.color ="black",
    8. vertex.border=V(g)$point.col,
    9. ##节点大小设置参数##
    10. shape = 1,# 设置点形状
    11. vertex.size=V(g)$degree*2,
    12. rescale =TRUE, # 默认设置
    13. # 函数对设置的图节点大小进行vertex.size <- 1/200 * params("vertex", "size")等调整,因此节点大小与图例设置的节点大小不一致。需要手动调整。
    14. ##节点标签设置参数##
    15. vertex.label=g$name,
    16. vertex.label.cex=0.8,
    17. vertex.label.dist=0, # 标签距离节点中心的距离,0表示标签在节点中心。
    18. #vertex.label.degree = pi/4, # 标签对于节点的位置,0-右,pi-左,-pi/2-上,pi/2-下。
    19. vertex.label.col="black",
    20. ##设置节点分组列表,绘制分组背景色##
    21. mark.groups =list(V(g)$name[V(g)$type %in% names(color)[1]],
    22. V(g)$name[V(g)$type %in% names(color)[2]],
    23. V(g)$name[V(g)$type %in% names(color)[3]]
    24. ), #
    25. mark.col=color,
    26. mark.border=color,
    27. #mark.expand = 1, # 设置背景阴影大小,1表示阴影边框刚全包节点。
    28. ##链接属性参数以edge*开头##
    29. edge.arrow.size=0.5,
    30. edge.width=abs(E(g)$r)*2,
    31. edge.curved = TRUE
    32. )
    33. ##设置图例,与plot.igraph()函数一起运行##
    34. legend(
    35. title = "Type",
    36. list(x = min(layout1[,1])-0.2,
    37. y = min(layout1[,2])-0.17), # 图例的位置需要根据自己的数据进行调整,后面需要使用AI手动调整。
    38. legend = c(unique(V(g)$type)),
    39. fill = color,
    40. #pch=1
    41. )
    42. legend(
    43. title = "|r-value|",
    44. list(x = min(layout1[,1])+0.4,
    45. y = min(layout1[,2])-0.17),
    46. legend = c(0.6,0.8,1.0),
    47. col = "black",
    48. lty=1,
    49. lwd=c(0.6,0.8,1.0)*2,
    50. )
    51. legend(
    52. title = "Correlation (±)",
    53. list(x = min(layout1[,1])+0.8,
    54. y = min(layout1[,2])-0.17),
    55. legend = c("positive","negative"),
    56. col = c("red",rgb(0,147,0,maxColorValue = 255)),
    57. lty=1,
    58. lwd=1
    59. )
    60. legend(
    61. title = "Degree",
    62. list(x = min(layout1[,1])+1.2,
    63. y = min(layout1[,2])-0.17),
    64. legend = c(1,seq(0,8,2)[-1]),# V(g)$degree。
    65. col = "black",
    66. pch=1,
    67. pt.lwd=1,
    68. pt.cex=c(1,seq(0,8,2)[-1])
    69. # 设置相同数值,igraph与legend生成的节点大小不一样,
    70. # 图例节点差不多是图节点的2倍大,这里通过设置图节点大小为degree*2解决,需要手动调整。
    71. )
    72. dev.off()

    图12|径向布局分组网络图,network_group_circle.pdf。图例位置需要AI或pdf编辑器调整一下。不想标签放在节点上,也可AI调整。

    4.4 绘制fr布局网络图

        fr布局(Fruchterman-Reingold 算法的力导向布局)适合变量较多的数据。

    1. ### 4.4 绘制fr布局网络图-不添加背景色
    2. pdf("network_group_fr.pdf",family = "Times",width = 10,height = 12)
    3. par(mar=c(5,2,1,2))
    4. plot.igraph(g, layout=layout2,#更多参数设置信息?plot.igraph查看。
    5. ##节点颜色设置参数##
    6. vertex.color=V(g)$point.col,
    7. vertex.frame.color ="black",
    8. vertex.border=V(g)$point.col,
    9. ##节点大小设置参数##
    10. vertex.size=V(g)$degree*2,
    11. ##节点标签设置参数##
    12. vertex.label=g$name,
    13. vertex.label.cex=0.8,
    14. #vertex.label.dist=0, # 标签距离节点中心的距离,0表示标签在节点中心。
    15. #vertex.label.degree = 0, # 标签对于节点的位置,0-右,pi-左,-pi/2-上,pi/2-下。
    16. vertex.label.col="black",
    17. ##链接属性参数以edge*开头##
    18. edge.arrow.size=0.5,
    19. edge.width=abs(E(g)$r)*2,
    20. edge.curved = TRUE
    21. )
    22. ##设置图例,与plot.igraph()函数一起运行##
    23. legend(
    24. title = "Type",
    25. list(x = min(layout1[,1])-0.2,
    26. y = min(layout1[,2])-0.17), # 图例的位置需要根据自己的数据进行调整,后面需要使用AI手动调整。
    27. legend = c(unique(V(g)$type)),
    28. fill = color,
    29. #pch=1
    30. )
    31. legend(
    32. title = "|r-value|",
    33. list(x = min(layout1[,1])+0.4,
    34. y = min(layout1[,2])-0.17),
    35. legend = c(0.6,0.8,1.0),
    36. col = "black",
    37. lty=1,
    38. lwd=c(0.6,0.8,1.0)*2,
    39. )
    40. legend(
    41. title = "Correlation (±)",
    42. list(x = min(layout1[,1])+0.8,
    43. y = min(layout1[,2])-0.17),
    44. legend = c("positive","negative"),
    45. col = c("red",rgb(0,147,0,maxColorValue = 255)),
    46. lty=1,
    47. lwd=1
    48. )
    49. legend(
    50. title = "Degree",
    51. list(x = min(layout1[,1])+1.2,
    52. y = min(layout1[,2])-0.17),
    53. legend = c(1,seq(0,8,2)[-1]),# max(V(g)$degree)
    54. col = "black",
    55. pch=1,
    56. pt.lwd=1,
    57. pt.cex=c(1,seq(0,8,2)[-1])
    58. )
    59. dev.off()

    图13|fr布局变量分组网络图,network_group_fr.pdf。

    4.5 绘制grid布局网络图

    1. ### 4.5 绘制grid布局网络图-不添加背景色
    2. pdf("network_group_grid.pdf",family = "Times",width = 10,height = 12)
    3. par(mar=c(5,2,1,2))
    4. plot.igraph(g, layout=layout3,#更多参数设置信息?plot.igraph查看。
    5. ##节点颜色设置参数##
    6. vertex.color=V(g)$point.col,
    7. vertex.frame.color ="black",
    8. vertex.border=V(g)$point.col,
    9. ##节点大小设置参数##
    10. vertex.size=V(g)$degree*2,
    11. ##节点标签设置参数##
    12. vertex.label=g$name,
    13. vertex.label.cex=0.8,
    14. vertex.label.dist=0, # 标签距离节点中心的距离,0表示标签在节点中心。
    15. vertex.label.degree = pi/2, # 标签对于节点的位置,0-右,pi-左,-pi/2-上,pi/2-下。
    16. vertex.label.col="black",
    17. ##链接属性参数以edge*开头##
    18. edge.arrow.size=0.5,
    19. edge.width=abs(E(g)$r)*2,
    20. edge.curved = TRUE,
    21. #edge.label.x = # 链接线标签位置横坐标。
    22. #edge.label.y = # 链接线标签位置纵坐标。
    23. )
    24. ##设置图例,与plot.igraph()函数一起运行##
    25. legend(
    26. title = "Type",
    27. list(x = min(layout1[,1])-0.2,
    28. y = min(layout1[,2])-0.17), # 图例的位置需要根据自己的数据进行调整,后面需要使用AI手动调整。
    29. legend = c(unique(V(g)$type)),
    30. fill = color,
    31. #pch=1
    32. )
    33. legend(
    34. title = "|r-value|",
    35. list(x = min(layout1[,1])+0.4,
    36. y = min(layout1[,2])-0.17),
    37. legend = c(0.6,0.8,1.0),
    38. col = "black",
    39. lty=1,
    40. lwd=c(0.6,0.8,1.0)*2,
    41. )
    42. legend(
    43. title = "Correlation (±)",
    44. list(x = min(layout1[,1])+0.8,
    45. y = min(layout1[,2])-0.17),
    46. legend = c("positive","negative"),
    47. col = c("red",rgb(0,147,0,maxColorValue = 255)),
    48. lty=1,
    49. lwd=1
    50. )
    51. legend(
    52. title = "Degree",
    53. list(x = min(layout1[,1])+1.2,
    54. y = min(layout1[,2])-0.17),
    55. legend = c(1,seq(0,8,2)[-1]),# max(V(g)$degree)
    56. col = "black",
    57. pch=1,
    58. pt.lwd=1,
    59. pt.cex=c(1,seq(0,8,2)[-1])
    60. )
    61. dev.off()

    图14|grid布局变量分组网络图,network_group_grid.pdf。

    参考资料

    https://hiplot-academic.com/basic/network-igraph

    微信公众号后台回复"network_group"或QQ群文件获取数据和代码。

    原文链接:R统计绘图-变量分组相关性网络图(igraph) (qq.com)


    EcoEvoPhylo :主要分享微生物生态和phylogenomics的数据分析教程。扫描上方二维码,关注EcoEvoPhylo。让我们大家一起学习,互相交流,共同进步。

    知乎 | 生态媛 

    学术交流QQ群 | 438942456

    学术交流微信群 |  jingmorensheng412

    加好友时,请备注姓名-单位-研究方向。 
     


    推荐阅读

    R绘图-物种、环境因子相关性网络图(简单图、提取子图、修改图布局参数、物种-环境因子分别成环径向网络图)

    R统计绘图-分子生态相关性网络分析(拓扑属性计算,ggraph绘图)

    R中进行单因素方差分析并绘图

    R统计绘图-多变量单因素非参数差异检验及添加显著性标记图

    R统计绘图-单因素Kruskal-Wallis检验

    R统计绘图-单、双、三因素重复测量方差分析[Translation]

    R统计-多变量单因素参数、非参数检验及多重比较

    R统计-多变量双因素参数、非参数检验及多重比较

    R绘图-KEGG功能注释组间差异分面条形图

    R绘图-相关性分析及绘图

    R绘图-相关性系数图

    R统计绘图-环境因子相关性热图

    R绘图-RDA排序分析

    R统计-VPA分析(RDA/CCA)

    R统计绘图-RDA分析、Mantel检验及绘图

    R统计-PCA/PCoA/db-RDA/NMDS/CA/CCA/DCA等排序分析教程

    R统计-正态性分布检验[Translation]

    R统计-数据正态分布转换[Translation]

    R统计-方差齐性检验[Translation]

    R统计-Mauchly球形检验[Translation]

    ​R统计绘图-混合方差分析[Translation]

    R统计绘图-协方差分析[Translation]

    R统计绘图-RDA分析、Mantel检验及绘图

    R统计绘图-factoextra包绘制及美化PCA结果图

    R统计绘图-环境因子相关性+mantel检验组合图(linkET包介绍1)

    R统计绘图-随机森林分类分析及物种丰度差异检验组合图

    机器学习-分类随机森林分析(randomForest模型构建、参数调优、特征变量筛选、模型评估和基础理论等)


  • 相关阅读:
    Spring中的Environment外部化配置管理详解
    Excel 通过条件格式自动添加边框
    ON1 Photo RAW 2024照片编辑器「Mac」
    【线性代数基础进阶】向量-补充+练习
    虹科 | 解决方案 | 新能源车EV测试解决方案
    构建健康游戏环境:DFA算法在敏感词过滤的应用
    vue3响应式原理:Proxy + Reflect
    小龙虾优化算法COA求解不闭合SD-MTSP,可以修改旅行商个数及起点(提供MATLAB代码)
    自动创建word文档的exe文件,自定义文件名、保存路径
    数据分析技能点-数据挖掘及入门
  • 原文地址:https://blog.csdn.net/qq_39859424/article/details/126801700