R語言分析3:加權相關網絡分析(WGCNA)

加權基因共表達網絡分析(WGCNA, Weighted gene co-expression network analysis)是一種用來描述不同樣品之間基因關聯模式的系統生物學方法,可以用來鑒定高度協同變化的基因集, 并根據基因集的內連性和基因集與表型之間的關聯鑒定候補生物標記基因或治療靶點。相比于只關注差異表達的基因,WGCNA利用數千或近萬個變化最大的基因或全部基因的信息識別感興趣的基因集,并與表型進行顯著性關聯分析。一是充分利用了信息,二是把數千個基因與表型的關聯轉換為數個基因集與表型的關聯,免去了多重假設檢驗校正的問題。

專有名詞:
? 共表達網絡:定義為加權基因網絡。點代表基因,邊代表基因表達相關性
? Module(模塊):高度內連的基因集。在無向網絡中,模塊內是高度相關的基因;在有向網絡中,模塊內是高度正相關的基因。把基因聚類成模塊后,可以對每個模塊進行三個層次的分析:1. 功能富集分析查看其功能特征是否與研究目的相符;2. 模塊與性狀進行關聯分析,找出與關注性狀相關度最高的模塊;3. 模塊與樣本進行關聯分析,找到樣品特異高表達的模塊
? 連接度(Connectivity):類似于網絡中 "度"(degree)的概念。每個基因的連接度是與其相連的基因的邊屬性之和
? 鄰接矩陣(Adjacency matrix):基因和基因之間的加權相關性值構成的矩陣
? Intramodular connectivity:模內連通性測量,給定基因相對于特定模塊的基因如何連接或共表達,判斷基因所屬關系
? Module eigengene E:給定模型的第一主成分,代表整個模型的基因表達譜,可很好的用一個向量代替了一個矩陣,方便后期計算
? Eigengene signi?cance:當獲得微陣列樣品特征y(例如病例對照狀態或體重)時,可以將模塊特征基因與此結果相關聯, 相關系數稱為特征基因顯著性
? Module Membership KME對于每個基因,通過將其基因表達譜與給定模塊的模塊本征基因相關聯來定義模塊成員的“模糊”度量。如,MM^{blue}(i) = K_{cor,r}^{blue} = cor(x^i,E^{blue})用來測量基因i與藍色模塊特征基因的相關程度。若MM^{blue}(i)接近0,則第i個基因不屬于blue模塊的一部分,相反,MM^{blue}(i)接近于1或 -1,則它與藍色模塊基因高度相關(正或負)。
? Gene signi?cance GS:GS_i的絕對值越高,第i個基因的生物學意義就越大。
? Module signi?cance:給定模塊中所有基因的平均絕對基因顯著性的度量。 當將基因顯著性定義為基因表達與外部性狀y的相關性時,此度量往往與模塊特征基因與y的相關性高度相關
? TOM (Topological overlap matrix):把鄰接矩陣轉換為拓撲重疊矩陣,以降低噪音和假相關,獲得的新距離矩陣,這個信息可拿來構建網絡或繪制TOM圖
? Hub gene:關鍵基因 (連接度最多或連接多個模塊的基因)
? 軟閾值:相關性值進行冪次運算冪次的值也就是軟閾值;

WGCNA-1

1. 數據輸入、清洗和預處理

1.1 加載基因表達數據

library(WGCNA)

dim(FPKM) # 仍選取TCGA- LUAD的FPKM數據
## [1] 59427   600

## 篩選中位絕對偏差前75%的基因,至少MAD大于0.01
## 篩選后會降低運算量,也會失去部分信息
## 也可不做篩選,使MAD大于0即可
m.mad <- apply(FPKM, 1, mad)
dataExprVar <- FPKM[which(m.mad > max(quantile(m.mad, probs = seq(0, 1, 0.25))[2], 0.01)),]
# 過濾基因,選取絕對中位差Top5000的基因
# dataExprVar <- t(exp[order(apply(FPKM, 1, mad), decreasing = T)[1:5000],])
dim(dataExprVar)
## [1] 30976   600

## 轉換為樣品在行,基因在列的矩陣
LUAD_Expr0 <- as.data.frame(t(dataExprVar))

注意:并不推薦使用差異基因作為輸入矩陣,通過差異表達基因過濾將會導致一個(或幾個高度相關的)基因聚成一個模塊,同時,也破壞了無標度拓撲的假設,所以通過無標度拓撲擬合來選擇軟閾值的將會失敗

1.2 數據清洗

## 檢測缺失值
gsg = goodSamplesGenes(LUAD_Expr0, verbose = 3)
gsg$allOK;
## 1] TRUE

# 若樣本檢查語句返回TRUE,那么沒有缺失值。否則,可通過以下代碼來移除缺失值
if (!gsg$allOK){
  # Optionally, print the gene and sample names that were removed:
  if (sum(!gsg$goodGenes)>0) 
    printFlush(paste("Removing genes:", 
                     paste(names(LUAD_Expr0)[!gsg$goodGenes], collapse = ",")));
  if (sum(!gsg$goodSamples)>0) 
    printFlush(paste("Removing samples:", 
                     paste(rownames(LUAD_Expr0)[!gsg$goodSamples], collapse = ",")));
  # Remove the offending genes and samples from the data:
  LUAD_Expr0 = LUAD_Expr0[gsg$goodSamples, gsg$goodGenes]
}

## 對樣本進行聚類(與隨后的基因聚類相比),看看是否有明顯的異常值
# hclusts聚類算法, dist計算基因之間的距離
sampleTree = hclust(dist(LUAD_Expr0), method = "average");
# 設置文字大小
par(cex = 0.2);
# 設置圖像邊距c(bottom, left, top, right) 
par(mar = c(0,4,2,0))
# 畫圖 main標題,sub子標題,xlab x軸標題,cex.lab標題字體大小,cex.axis坐標軸刻度大小,cex.main主標題字體
plot(sampleTree, main = "Sample clustering to detect outliers", sub="", xlab="", cex.lab = 1.5, cex.axis = 1.5, cex.main = 5)

# 在上圖上畫紅線
abline(h = 1e+05, col = "red");
# Determine cluster under the line
# 剪枝算法,cutHeight 修剪樹枝的高度 minSize集群最小數
clust = cutreeStatic(sampleTree, cutHeight = 1e+05, minSize = 5)
# 剪枝結果
table(clust)
## clust
##   0   1   2 
##   2 591   7 

# clust 1 contains the samples we want to keep
keepSamples = (clust==1)
# 符合要求的數據
LUAD_Expr = LUAD_Expr0[keepSamples, ]

# 提取行和列
nSamples = nrow(LUAD_Expr)
nGenes = ncol(LUAD_Expr)
WGCNA-2

★ 此處去除左側9個樣本

1.3 加載臨床特征數據

# 讀取臨床數據
LUAD_clin0 <- jsonlite::fromJSON("/data/shumin/Cibersort/LUAD/clinical.cart.2023-06-08.json")
n = length(LUAD_clin0$diagnoses)

# 提取數據
case_id = classfication_of_tumor = c(rep(0, n))
tumor_stage = gender = c(rep(0, n))
year_to_birth = year_to_death =  c(rep(0, n))
year_to_diagnosis = days_to_death = c(rep(0, n))
age = deadORlive = race = alcohol = smoked = c(rep(0, n))

for (i in 1:n) {
  case_id[i] = LUAD_clin0$case_id[[I]]
  classfication_of_tumor[i] = LUAD_clin0$diagnoses[[i]]$classification_of_tumor
  tumor_stage[i] = LUAD_clin0$diagnoses[[i]]$tumor_grade
  gender[i] = LUAD_clin0$demographic$gender[[I]]
  year_to_birth[i] = ifelse(
    is.null(LUAD_clin0$demographic$year_of_birth[[i]]),
    "notReport",
    LUAD_clin0$demographic$year_of_birth[[I]]
  )
  year_to_death[i] = ifelse(
    is.null(LUAD_clin0$demographic$year_of_death[[i]]),
    "notReport",
    LUAD_clin0$demographic$year_of_death[[I]]
  )
  year_to_diagnosis[i] = ifelse(
    is.null(LUAD_clin0$diagnoses[[i]]$year_of_diagnosis),
    "notReport",
    LUAD_clin0$diagnoses[[i]]$year_of_diagnosis
  )
  days_to_death[i] = ifelse(
    is.null(LUAD_clin0$demographic$days_to_death[[i]]),
    "notReport",
    LUAD_clin0$demographic$days_to_death[[I]]
  )
  age[i] = ifelse(
    is.null(LUAD_clin0$demographic$age_at_index[[i]]),
    "notReport",
    LUAD_clin0$demographic$age_at_index[[I]]
  )
  deadORlive[i] = ifelse(
    is.null(LUAD_clin0$demographic$vital_status[[i]]),
    "notReport",
    LUAD_clin0$demographic$vital_status[[I]]
  )
  race[i] = ifelse(
    is.null(LUAD_clin0$demographic$race[[i]]),
    "notReport",
    LUAD_clin0$demographic$race[[I]]
  )
  alcohol[i] = ifelse(
    is.null(LUAD_clin0$exposures[[i]]$alcohol_history),
    "notReprot",
    LUAD_clin0$exposures[[i]]$alcohol_history
  )
  smoked[i] = ifelse(
    is.null(LUAD_clin0$exposures[[i]]$years_smoked),
    "notReport",
    LUAD_clin0$exposures[[i]]$years_smoked
  )
}

LUAD_clin1 <- data.frame(
  case_id,
  classfication_of_tumor,
  tumor_stage,
  gender,
  year_to_birth,
  year_to_death,
  year_to_diagnosis,
  days_to_death,
  age,
  deadORlive,
  race,
  alcohol,
  smoked
)

head(LUAD_clin1)
##                                case_id classfication_of_tumor  tumor_stage gender year_to_birth year_to_death year_to_diagnosis days_to_death age deadORlive                      race      alcohol smoked
##  1 a3fd20b2-e001-44ab-9716-754e5ae70808           not reported not reported female          1935            NA              2012            NA  77      Alive                     white Not Reported     NA
##  2 25d4ea9e-f773-4f11-bac9-64efdad73211           not reported not reported female          1950            NA              2009            NA  59      Alive                     white Not Reported     45
##  3 a52e99d6-a61a-439d-b0b1-ca7a0eabcb04           not reported not reported female          1969            NA              2011            NA  42      Alive                     white Not Reported      2
##  4 27fceec1-3298-4cdd-a4e6-8f5cf34604f0           not reported not reported   male          1957            NA              2010            NA  53      Alive black or african american Not Reported     NA
##  5 2923e404-38f2-437a-b57e-23401fbe0273           not reported not reported   male          1965            NA              2011            NA  46      Alive                     white Not Reported     NA
##  6 a65700c2-e58c-4fd4-aeb1-5686b8f4d212           not reported not reported   male          1935            NA              2009            NA  74      Alive                     white Not Reported     NA

# 讀取meta數據(用于id轉換)
LUAD_meta <- jsonlite::fromJSON("/data/shumin/Cibersort/LUAD/metadata.cart.2023-06-08.json")
sample_id <- sapply(LUAD_meta$associated_entities, function(x){x[,1]})
case_id <- sapply(LUAD_meta$associated_entities, function(x){x[,3]})
anno_data <- data.frame(sample_id, case_id) 

head(anno_data)
##                      sample_id                              case_id
##  1 TCGA-44-8120-01A-11R-2241-07 83e38dbd-edab-47f2-b19f-6ea38fc6bece
##  2 TCGA-99-8025-01A-11R-2241-07 84c3ba70-afa7-4b69-be69-7ec8d6022c56
##  3 TCGA-50-6594-01A-11R-1755-07 8504fd86-a70a-4cba-9ec8-25c9e60ca549
##  4 TCGA-78-7161-01A-11R-2039-07 86faf16c-56fd-4b7b-a6b2-b4c83bec93e1
##  5 TCGA-55-7903-01A-11R-2170-07 77c4dbb2-eceb-4e0d-bcde-63dc817d5f35
##  6 TCGA-38-4632-01A-01R-1755-07 875333ab-9048-462d-aaa2-693ad127e3cc

LUAD_clin2 <- merge(anno_data, LUAD_clin1, by = "case_id")

LUAD_clin3 <- LUAD_clin2[, c("sample_id","gender","year_to_birth","year_to_death","year_to_diagnosis","days_to_death", "age","deadORlive","race","smoked")] # 選取后續分析需要的列
LUAD_clin3$gender <-  ifelse(LUAD_clin3$gender == 'female', 1, 2)
LUAD_clin3$deadORlive <- ifelse(LUAD_clin3$deadORlive == 'Alive', 0, 1)
LUAD_clin3$race <- ifelse(LUAD_clin3$race == 'not reported', 0, 
                          ifelse (LUAD_clin3$race == 'american indian or alaska native', 1,
                                  ifelse(LUAD_clin3$race == 'asian', 2,
                                         ifelse(LUAD_clin3$race == 'black or african american', 3, 4))))

# 形成一個類似于表達數據的數據框架,以保存臨床特征
# 提取行名
LUAD_Samples = rownames(LUAD_Expr)
# 數據匹配 返回匹配行
Trait_Rows = match(LUAD_Samples, LUAD_clin3$sample_id);
# 提取指定要求行
data_Traits = LUAD_clin3[Trait_Rows, -1];
# 提取行名
rownames(data_Traits) = LUAD_clin3[Trait_Rows, 1];
# 垃圾回收
collectGarbage();

# Re-cluster samples
# 畫聚類圖
LUAD_Tree = hclust(dist(LUAD_Expr), method = "average")
# Convert traits to a color representation: white means low, red means high, grey means missing entry
# 畫表型的熱圖
# 將特征轉換為顏色表示:白色表示低,紅色表示高,灰色表示缺少條目
# 如果signed為true 以綠色開頭代表最大負值,以白色開頭代表零附近的值,然后變為紅色代表正值
traitColors = numbers2colors(data_Traits, signed = FALSE);
# Plot the sample dendrogram and the colors underneath.
# 繪制出樹狀圖和下面的顏色 
plotDendroAndColors(LUAD_Tree, traitColors, groupLabels = names(data_Traits), dendroLabels = FALSE, main = "LUAD dendrogram and trait heatmap")
WGCNA-3

2. 建設表達網絡與模塊檢測

此步驟是使用WGCNA方法進行所有網絡分析的基礎。WGCNA提出三種不同的方法構建網絡并識別模塊:

\ ? 使用方便的一步網絡結構和模塊檢測功能,適合希望以最小努力達到結果的用戶;
\ ? 為希望使用定制/替代方法進行實驗的用戶逐步構建網絡和模塊檢測
\ ? 一種自動分塊網絡結構和模塊檢測方法,適用于希望分析太大而無法同時分析的數據集的用戶。

2.1 自動一步構建網絡與模塊檢測

2.1.1 軟閾值的選擇:網絡拓撲分析

構建一個加權基因網絡需要選擇軟閾值冪β來計算鄰接矩陣權重參數,即將基因間的相關系數進行乘方運算來表征其相關性,首先需要確定乘方的值

# Choose a set of soft-thresholding powers
# 給出候選的β值,c(1:10)表示1到10;seq(from = 12, to = 20, by = 2)表示從12開始間隔兩個數到20
powers = c(c(1:10), seq(from = 12, to = 20, by = 2))
powers
# Call the network topology analysis function 調用網絡拓撲分析函數
# verbose表示輸出結果詳細程度
sft = pickSoftThreshold(LUAD_Expr, powerVector = powers, verbose = 0);

# sft這中保存了每個powers值計算出來的網絡特征,其中powerEstimate就是最佳power值,fitIndices保存了每個power對應的網絡的特征。
str(sft)
## List of 2
##  $ powerEstimate: num 2
##  $ fitIndices   :'data.frame':   15 obs. of  7 variables:
##   ..$ Power         : num [1:15] 1 2 3 4 5 6 7 8 9 10 ...
##   ..$ SFT.R.sq      : num [1:15] 0.123 0.916 0.916 0.932 0.938 ...
##   ..$ slope         : num [1:15] -0.295 -1 -0.996 -0.964 -0.954 ...
##   ..$ truncated.R.sq: num [1:15] 0.393 0.921 0.94 0.933 0.925 ...
##   ..$ mean.k.       : num [1:15] 4171 1288 613 364 244 ...
##   ..$ median.k.     : num [1:15] 3579.7 676.1 173.7 54 19.4 ...
##   ..$ max.k.        : num [1:15] 9260 5325 3783 2938 2403 ...

# Plot the results 結果繪圖
# 設置圖的顯示一行兩列
par(mfrow = c(1,2));
cex1 = 0.9;
# Scale-free topology fit index as a function of the soft-thresholding power
# 生成閾值和網絡的特征之間的關系函數
plot(sft$fitIndices[,1], -sign(sft$fitIndices[,3])*sft$fitIndices[,2],
     xlab="Soft Threshold (power)",ylab="Scale Free Topology Model Fit,signed R^2",type="n",
     main = paste("Scale independence"))
text(sft$fitIndices[,1], -sign(sft$fitIndices[,3])*sft$fitIndices[,2],
     labels = powers,cex = cex1, col = "red");
# this line corresponds to using an R^2 cut-off of h
abline(h = 0.90, col = "red")

# sft$fitIndices 保存了每個power構建的相關性網絡中的連接度的統計值,k就是連接度值,每個power值提供了max, median, max3種連接度的統計量
# 對連接度的均值進行可視化
# Mean connectivity as a function of the soft-thresholding power
plot(sft$fitIndices[,1], sft$fitIndices[,5],
     xlab = "Soft Threshold (power)", ylab = "Mean Connectivity", type = "n",
     main = paste("Mean connectivity"))
text(sft$fitIndices[,1], sft$fitIndices[,5], labels = powers, cex = cex1, col = "red")

WGCNA-4

R^{2}為無尺度網絡評價系數,一般設置為0.9, β取值標準:R^{2}第一次到達0.9時對應的β
★ 橫坐標為軟閾值的梯度,第一幅圖的縱坐標為無標度網絡適應系數,越大越好;第二幅圖的縱坐標為節點的平均連通度,越小越好

2.1.2 一步構建網絡與模塊檢測

# 打開多線程
enableWGCNAThreads(nThreads = 10) 

# LUAD_Expr表達數據,TOMType拓撲重疊矩陣計算方式,minModuleSize用于模塊檢測的最小模塊尺寸,
# reassignThreshold 是否在模塊之間重新分配基因的p值比率閾值,mergeCutHeight 樹狀圖切割高度
# numericLabels 返回的模塊應該用顏色(FALSE)還是數字(TRUE)標記,pamRespectsDendro樹狀圖相關參數
# saveTOMs 字符串的向量,saveTOMFileBase 包含包含共識拓撲重疊文件的文件名庫的字符串
net = blockwiseModules(LUAD_Expr, power = sft$powerEstimate, 
                       maxBlockSize = 2000, # 最大模塊數量
                       TOMType = "unsigned", minModuleSize = 30, reassignThreshold = 0, # 構建無尺度網絡,最小模塊基因數為30
                       mergeCutHeight = 0.25, # 需要合并模塊的閾值
                       numericLabels = TRUE, # 以數字作為模塊的名字
                       pamRespectsDendro = FALSE, saveTOMs = TRUE,
                       saveTOMFileBase = "LUADTOM", verbose = 3)

# 回到網絡分析,查看標識了多少個模塊以及模塊大小
table(net$colors)
## 
##    0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56 
##  4348 9126 1444 1202 1158 1141  969  725  581  531  444  425  391  359  324  317  280  274  263  252  225  186  178  152  150  142  137  128  125  118  115  115  114  112  112  108  108  106  100   96   96   92   92   90   89   88   83   82   81   81   81   80   80   79   78   78   77 
##    57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79   80   81   82   83   84   85   86   87   88   89   90   91   92   93   94   95   96   97   98   99  100  101  102  103  104 
##    74   74   74   68   67   64   64   64   62   61   60   59   58   57   56   55   55   54   52   52   52   52   50   50   50   49   49   49   47   45   43   43   39   39   38   38   38   36   36   36   34   34   33   33   33   31   31   30 

# 將標簽轉化為繪圖顏色
moduleColors = labels2colors(net$colors)
# 繪制樹狀圖和下面的模塊顏色
# dendroLabels樹狀圖標簽。設置為FALSE完全禁用樹狀圖標簽;設置為NULL使用的行標簽LUAD_Expr
# addGuide是否應在樹狀圖中添加垂直的“指導線”?線條使識別單個樣本的顏色代碼更加容易。
plotDendroAndColors(net$dendrograms[[1]], moduleColors[net$blockGenes[[1]]], "Module colors",
                    dendroLabels = FALSE, hang = 0.03, addGuide = TRUE, guideHang = 0.05)
WGCNA-5

★ 指示有104個模塊,按大小降序標記為1至104,大小范圍為9126至30個基因; 標簽0保留用于所有模塊外部的基因
★ 無法聚類到模塊中的基因會標示為灰色,如果灰色區域較多,可能由于樣本中基因共表達趨勢不明顯,可能需要調整基因過濾的方法

# 保存后續分析所需的模塊分配和模塊本征信息,可由recutBlockwiseTrees函數應用修改后的條件而不必重新計算網絡和聚類樹狀圖
moduleLabels = net$colors
moduleColors = labels2colors(net$colors)
MEs = net$MEs;
geneTree = net$dendrograms[[1]];
save(MEs, moduleLabels, moduleColors, geneTree, file = "TCGA-LUAD-02-networkConstruction-auto.RData")

2.2 分步網絡構建和模塊檢測

https://horvath.genetics.ucla.edu/html/CoexpressionNetwork/Rpackages/WGCNA/Tutorials/FemaleLiver-02-networkConstr-man.pdf

2.3 逐塊網絡構建和模塊檢測

https://horvath.genetics.ucla.edu/html/CoexpressionNetwork/Rpackages/WGCNA/Tutorials/FemaleLiver-02-networkConstr-blockwise.pdf

3. 分步網絡構建和模塊檢測

3.1 量化模塊-特質關聯

在此分析中,我們想確定與所測量的臨床特征顯著相關的模塊。 由于我們已經為每個模塊建立了一個概要文件(特征基因),因此我們只需將特征基因與外部特征相關聯,然后尋找最重要的關聯,實際上是計算模塊的ME值與表型的相關系數:

# Define numbers of genes and samples
# 獲得基因數和樣本數
nGenes = ncol(LUAD_Expr);
nSamples = nrow(LUAD_Expr);

# Recalculate MEs with color labels
# 用彩色標簽重新計算MEs
# 在給定的單個數據集中計算模塊的模塊本征基因
MEs0 = moduleEigengenes(LUAD_Expr, moduleColors)$eigengenes
# 對給定的(特征)向量進行重新排序,以使相似的向量(通過相關性度量)彼此相鄰
MEs = orderMEs(MEs0)

# 計算module的ME值與表型的相關系數(pearson)
moduleTraitCor = cor(MEs, data_Traits, use = "p");
moduleTraitPvalue = corPvalueStudent(moduleTraitCor, nSamples);
# 使用的是其他相關性方法,則可以使用 bicorAndPvalue 函數來計算顯著性
# modTraitCorP = bicorAndPvalue(MEs_col, design)
# modTraitCor = modTraitCorP$bicor
# modTraitP   = modTraitCorP$p

names(MEs)
##   [1] "MEdarkgrey"        "MEyellowgreen"     "MEivory"           "MEnavajowhite1"    "MEindianred3"      "MElightcyan"       "MEgreenyellow"     "MEskyblue1"        "MEbisque4"         "MEblack"           "MEbrown"           "MEmagenta"         "MEmidnightblue"    "MEpalevioletred3" 
##   [15] "MEskyblue4"        "MEmediumpurple1"   "MEthistle1"        "MEblue2"           "MEorangered3"      "MEdarkviolet"      "MEplum1"           "MEthistle"         "MEdarkred"         "MEwhite"           "MEfirebrick3"      "MEblueviolet"      "MEsienna4"         "MElightsteelblue" 
##   [29] "MElightyellow"     "MEpalevioletred2"  "MEcoral3"          "MEpink4"           "MEhoneydew"        "MEyellow3"         "MEnavajowhite2"    "MEcoral1"          "MEtan"             "MEblue"            "MEdarkolivegreen"  "MEthistle3"        "MEdarkseagreen4"   "MEplum3"          
##   [43] "MEbrown2"          "MElavenderblush3"  "MEhoneydew1"       "MElightslateblue"  "MEdarkolivegreen4" "MEdarkturquoise"   "MEviolet"          "MEcoral"           "MEpink"            "MEmagenta4"        "MEfirebrick4"      "MEpurple"          "MEred"             "MElightcoral"     
##   [57] "MEyellow"          "MEmediumpurple4"   "MEskyblue"         "MEcyan"            "MEdarkgreen"       "MElightpink4"      "MEskyblue2"        "MEmediumorchid"    "MElightsteelblue1" "MEmaroon"          "MEmediumpurple2"   "MEplum2"           "MEsteelblue"       "MEdarkorange2"    
##   [71] "MEplum"            "MEdarkmagenta"     "MEorange"          "MEdarkorange"      "MEsalmon"          "MElightgreen"      "MEturquoise"       "MEroyalblue"       "MEyellow4"         "MEorangered4"      "MEpaleturquoise"   "MElightblue4"      "MEindianred4"      "MEbrown4"         
##   [85] "MEsalmon4"         "MEsienna3"         "MEthistle2"        "MEgrey60"          "MEgreen"           "MEorangered1"      "MEmediumpurple3"   "MEdarkslateblue"   "MElightpink3"      "MEantiquewhite2"   "MElightcyan1"      "MEfloralwhite"     "MElavenderblush2"  "MEdarkolivegreen2"
##   [99] "MEskyblue3"        "MEsalmon2"         "MEcoral2"          "MEsaddlebrown"     "MEantiquewhite4"   "MEdarkseagreen3"   "MEgrey" 

# sizeGrWindow(10,6)
# 顯示相關性及其p值
textMatrix = paste(signif(moduleTraitCor, 2), "\n(",signif(moduleTraitPvalue, 1), ")", sep = "");
dim(textMatrix) = dim(moduleTraitCor)
# Display the correlation values within a heatmap plot\
# ySymbols 當ylabels使用時所使用的其他標簽; colorLabels 應該使用顏色標簽嗎
# colors 顏色; textMatrix 單元格名字
labeledHeatmap(Matrix = moduleTraitCor, xLabels = names(data_Traits), yLabels = names(MEs), ySymbols = names(MEs),
               colorLabels = FALSE,colors = greenWhiteRed(50), textMatrix = textMatrix,setStdMargins = FALSE,
               cex.text = 0.2, zlim = c(-1,1),
               main = paste("Module-trait relationships"))

WGCNA-6

★ 計算出模塊與表型之間相關性之后,可以挑選最相關的那些模塊來進行后續分析。但是,模塊本身可能還包含很多的基因,還需要進一步識別關鍵基因

3.2 基因與性狀和重要模塊的關系:基因重要性和模塊成員

量化陣列上所有基因與每個模塊的相似性尋找重要模塊:

# 定義包含數據特征權重列的變量權重
days_to_death = as.data.frame(data_Traits$days_to_death);
names(days_to_death) = "days_to_death"
geneModuleMembership = as.data.frame(cor(LUAD_Expr, MEs, use = "p"));
# 模塊的名稱(顏色)substring提取文本從第3個字母開始(此處輸入法有問題,不用"#")
# modNames = substring(names(MEs), 3)
# 基因和模塊的相關系數
geneModuleMembership = as.data.frame(cor(LUAD_Expr, MEs, use = "p"));
MMPvalue = as.data.frame(corPvalueStudent(as.matrix(geneModuleMembership), nSamples));
names(geneModuleMembership) = paste("MM", modNames, sep = "");
names(MMPvalue) = paste("p.MM", modNames, sep="");

# gene和性狀的關系
geneTraitSignificance = as.data.frame(cor(LUAD_Expr, days_to_death, use = "p"));
GSPvalue = as.data.frame(corPvalueStudent(as.matrix(geneTraitSignificance), nSamples));
names(geneTraitSignificance) = paste("GS.", names(days_to_death), sep="");
names(GSPvalue) = paste("p.GS.", names(days_to_death), sep = "");

3.3 模內分析:鑒定具有高GS和MM的基因

使用GS和MM度量,我們可以鑒定出對“days_to_death”以及在感興趣的模塊中具有較高模塊成員性具有重要意義的基因。 例如,我們看一下與“days_to_death”關聯“brown”模塊。 我們在“brown”模塊中繪制了基因重要性與模塊成員關系的散點圖。 在此模塊中,GS和MM之間存在高度顯著的負相關性

# 模型顏色
module = "brown"
# 匹配列
column = match(module, modNames);
moduleGenes = moduleColors==module;
#sizeGrWindow(7, 7);
par(mfrow = c(1,1));
# MM <- abs(geneModuleMembership[moduleGenes, column])
# GS <- abs(geneTraitSignificance[moduleGenes, 1])
# 畫散點圖
verboseScatterplot(abs(geneModuleMembership[moduleGenes, column]),
                   abs(geneTraitSignificance[moduleGenes, 1]),
                   xlab = paste("Module Membership in", module, "module"),
                   ylab = "Gene significance for body weight",
                   main = paste("Module membership vs. gene significance\n"),
                   cex.main = 1.2, cex.lab = 1.2, cex.axis = 1.2, col = module)

WGCNA-7

★ GS是Gene Signicance,描述的是某一個基因性狀的相關性
★ MM是Module Membership,描述的是某一個基因模塊之間的相關性

3.4 導出模塊網絡

file <- "~/TCGA-LUAD.net"
TOM <- TOMsimilarityFromExpr(LUAD_Expr, power = 2, networkType = "unsigned")
dimnames(TOM) <- list(colnames(LUAD_Expr), colnames(LUAD_Expr))
modTOM <- TOM[moduleGenes, moduleGenes]

cyt <- exportNetworkToCytoscape(
  modTOM,
  edgeFile = paste0(file, module, ".edges.txt"),
  nodeFile = paste0(file, module, ".nodes.txt"),
  weighted = TRUE,
  threshold = 0, # threshold 默認為0.5, 可以根據自己的需要調整
  nodeNames = moduleGenes,
  nodeAttr = module
)

4. 使用WGCNA進行網絡可視化

4.1 顯示基因網絡

可視化加權網絡的一種方法是繪制其熱圖,熱圖的每一行和每一列都對應一個基因。 熱圖可以描述鄰接或拓撲重疊,淺色表示低鄰接(重疊),而深色表示更高的鄰接(重疊)。 另外,沿著熱圖的頂部和左側繪制了基因樹狀圖和模塊顏色。

# 重新計算拓撲重疊:通過保存TOM可以更有效地完成此操作
dissTOM = 1-TOMsimilarityFromExpr(LUAD_Expr, power = 2);
# 變換dissTOM(對dissTOM矩陣進行指數轉換,使中等強度的關系更容易在熱圖上展示出來);
plotTOM = dissTOM^7;
# #將對角線數據設為NA
diag(plotTOM) = NA;
# Call the plot function
# sizeGrWindow(9,9)
# 基因的聚類樹聚類時的距離為1-TOM值結合基因間的距離,即1-TOM值,用熱圖展示
# TOMplot(plotTOM, geneTree, moduleColors, main = "Network heatmap plot, all genes") # 此處我的基因數量過多?會報錯:Error in x[, iy] : subscript out of bounds

★ 數據不合理,可根據探針集或基因的平均表達量或方差(如中位數或絕對中位差)重新進行過濾,低表達或無變化的基因通常代表噪音。

# 限制基因數量以加快繪圖速度。 注意,一個基因子集的基因樹狀圖通常看起來與所有基因的基因樹狀圖不同:
nSelect = 400
# 為了反復重現結果, 這里設置了隨機種子;
set.seed(10);
select = sample(nGenes, size = nSelect);
# 提取抽取基因相應的TOM矩陣
selectTOM = dissTOM[select, select];
# 重新畫聚類圖
selectTree = hclust(as.dist(selectTOM), method = "average")
selectColors = moduleColors[select];
# Open a graphical window
# sizeGrWindow(9,9)
# Taking the dissimilarity to a power, say 10, makes the plot more informative by effectively changing
# the color palette; setting the diagonal to NA also improves the clarity of the plot
plotDiss = selectTOM^7;
diag(plotDiss) = NA;
# 更換配色
# mycolor <- gplots::colorpanel(250, 'red', "orange", 'lemonchiffon')
TOMplot(plotDiss, selectTree, selectColors,
        main = "Network heatmap plot, selected genes",
        # col = mycolor)
WGCNA-8

4.2 可視化特征基因網絡

研究找到的模塊之間的關系通常很有趣。 可以使用特征基因作為代表特征,并通過特征基因相關性來量化模塊相似性。 該軟件包包含一個方便的函數plotEigengeneNetworks,該函數生成特征基因網絡的摘要圖。 通常,向特征基因添加臨床特征(或多個特征)以了解特征如何適合特征基因網絡是有益的

# Recalculate module eigengenes
# 重新計算基因特征值
MEs = moduleEigengenes(LUAD_Expr, moduleColors)$eigengenes
# Isolate weight from the clinical traits
days_to_death = as.data.frame(data_Traits$days_to_death);
names(days_to_death) = "days_to_death"
# Add the weight to existing module eigengenes
MET = orderMEs(cbind(MEs, days_to_death))
# Plot the relationships among the eigengenes and the trait
# sizeGrWindow(5,7.5);
par(cex = 0.2)
# 畫樹形圖
# marDendro給出樹狀圖的邊距設置,marHeatmap熱圖邊距設置
plotEigengeneNetworks(MET, "",  marDendro = c(0,4,1,2), marHeatmap = c(3,4,1,2), cex.lab = 0.8, yLabelsAngle = 90)
WGCNA-9

拆分樹狀圖和熱圖圖

# Plot the dendrogram
# sizeGrWindow(6,6);
par(cex = 1.0)
plotEigengeneNetworks(MET, "Eigengene dendrogram", marDendro = c(0,4,2,0),
plotHeatmaps = FALSE)
# Plot the heatmap matrix (note: this plot will overwrite the dendrogram plot)
par(cex = 1.0)
plotEigengeneNetworks(MET, "Eigengene adjacency heatmap", marHeatmap = c(3,4,2,2),plotDendrograms = FALSE, yLabelsAngle = 90)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容