分享

GEO生信数据挖掘(四)数据清洗(离群值处理、低表达基因、归一化、log2处理)

 imtravelinghah 2023-11-08 发布于广西

检索到目标数据集后,开始数据挖掘,本文以阿尔兹海默症数据集GSE1297为例

目录

离群值处理

删除 低表达基因

函数归一化,矫正差异

数据标准化—log2处理

 完整代码


上节围绕着探针ID和基因名称做了一些清洗工作,还做了重复值检查,空值删除操作。

  1. #查看重复值
  2. table(duplicated(matrix$Gene.Symbol))
  3. #去掉缺失值
  4. matrix_na = na.omit(matrix)
  5. #基因名称为空删除
  6. matrix_final = matrix_na[matrix_na$Gene.Symbol != "",]

离群值处理

用于处理异常值,将超出一定范围的值替换为中位数,以减少异常值对后续分析的影响。

  1. #数据离群处理
  2. #处理极端值
  3. #定义向量极端值处理函数
  4. #用于处理异常值,将超出一定范围的值替换为中位数,以减少异常值对后续分析的影响。
  5. dljdz=function(x) {
  6. DOWNB=quantile(x,0.25)-1.5*(quantile(x,0.75)-quantile(x,0.25))
  7. UPB=quantile(x,0.75)+1.5*(quantile(x,0.75)-quantile(x,0.25))
  8. x[which(x<DOWNB)]=quantile(x,0.5)
  9. x[which(x>UPB)]=quantile(x,0.5)
  10. return(x)
  11. }
  12. #第一列设置为行名
  13. matrix_leave=matrix_final
  14. boxplot(matrix_leave,outline=FALSE, notch=T, las=2) ##出箱线图
  15. dim(matrix_leave)
  16. #处理离群值
  17. matrix_leave_res=apply(matrix_leave,2,dljdz)
  18. boxplot(matrix_leave_res,outline=FALSE, notch=T, las=2) ##出箱线图
  19. dim(matrix_leave_res)

删除 低表达基因

方案1 :仅去除在所有样本里表达量都为零的基因(或者平均值小于1)

方案2:仅保留在一半(50%,75%...自己选择)以上样本里表达的基因

  1. #删除 低表达基因
  2. #仅去除在所有样本里表达量都为零的基因(平均值小于1)
  3. # 计算基因表达矩阵的平均值
  4. gene_avg <- apply(matrix_final, 1, mean)
  5. # 根据阈值筛选低表达基因
  6. filtered_genes_1 <- matrix_final[gene_avg >= 1, ] # 表达量平均值小于1的过滤
  7. dim(filtered_genes_1)
  8. #+================================
  9. #常用过滤标准2(推荐):
  10. #仅保留在一半以上样本里表达的基因
  11. # 计算基因表达矩阵每个基因的平均值
  12. gene_means <- rowMeans(matrix_final)
  13. # 计算基因平均值的排序百分位数
  14. gene_percentiles <- rank(gene_means) / length(gene_means)
  15. # 获取阈值
  16. threshold <- 0.25 # 删除后25%的阈值
  17. #threshold <- 0.5 # 删除后50%的阈值
  18. # 根据阈值筛选低表达基因
  19. filtered_genes_2 <- matrix_final[gene_percentiles > threshold, ]
  20. # 打印筛选后的基因表达矩阵
  21. dim(filtered_genes_2)
  22. boxplot(filtered_genes_2,outline=FALSE, notch=T, las=2) ##出箱线图
  23. #dim(filtered_genes)
  24. #+删除 低表达基因 得到filtered_genes_1 删除平均表达小于1的 得到filtered_genes_2 删除后25%的

函数归一化,矫正差异


#1.归一化不是绝对必要的,但是推荐进行归一化。
#有重复的样本中,应该不具备生物学意义的外部因素会影响单个样品的表达,
#例如中第一批制备的样品会总体上表达高于第二批制备的样品,假设所有样品表达值的范围和分布都应当相似,
#需要进行归一化来确保整个实验中每个样本的表达分布都相似。
#2.归一化要在log2标准化之前做
 

  1. library(limma)
  2. exprSet=normalizeBetweenArrays(filtered_genes_2)
  3. boxplot(exprSet,outline=FALSE, notch=T, las=2) ##出箱线图
  4. ## 这步把矩阵转换为数据框很重要
  5. class(exprSet) ##注释:此时数据的格式是矩阵(Matrix)
  6. exprSet <- as.data.frame(exprSet)

数据标准化—log2处理

如果表达量的数值在50以内,通常是经过log2转化后的。如果数字在几百几千,则是未经转化的。

GSE数据集的注释部分会有说明,常见的标准化处理方法有3种:RMA算法、GC-RMA算法、MAS5算法

  1. #标准化 表达矩阵自动log2化
  2. qx <- as.numeric(quantile(exprSet, c(0., 0.25, 0.5, 0.75, 0.99, 1.0), na.rm=T))
  3. LogC <- (qx[5] > 100) ||
  4. (qx[6]-qx[1] > 50 && qx[2] > 0) ||
  5. (qx[2] > 0 && qx[2] < 1 && qx[4] > 1 && qx[4] < 2)
  6. ## 开始判断
  7. if (LogC) {
  8. exprSet [which(exprSet <= 0)] <- NaN
  9. ## 取log2
  10. exprSet_clean <- log2(exprSet)
  11. print("log2 transform finished")
  12. }else{
  13. print("log2 transform not needed")
  14. }

筛选后的基因表达矩阵的箱线图

经过数据清洗后的箱线图

 完整代码

  1. # 安装并加载GEOquery包
  2. library(GEOquery)
  3. # 指定GEO数据集的ID
  4. gse_id <- "GSE1297"
  5. # 使用getGEO函数获取数据集的基础信息
  6. gse_info <- getGEO(gse_id, destdir = ".", AnnotGPL = F ,getGPL = F) # Failed to download ./GPL96.soft.gz!
  7. # 提取基因表达矩阵
  8. expression_data <- exprs(gse_info[[1]])
  9. # 提取注释信息
  10. #annotation <- featureData(gse_info[[1]])
  11. #查看平台文件列名
  12. colnames(annotation)
  13. #打印项目文件列表
  14. dir()
  15. # 读取芯片平台文件txt
  16. platform_file <- read.delim("GPL96-57554.txt", header = TRUE, sep = "\t", comment.char = "#")
  17. #查看平台文件列名
  18. colnames(platform_file)
  19. # 假设芯片平台文件中有两列,一列是探针ID,一列是基因名
  20. #probe_names <- platform_file$ID
  21. #gene_symbols <- platform_file$Gene.Symbol
  22. platform_file_set=platform_file[,c(1,11)]
  23. #一个探针对应多个基因名,保留第一个基因名
  24. ids = platform_file_set
  25. library(tidyverse)
  26. test_function <- apply(ids,
  27. 1,
  28. function(x){
  29. paste(x[1],
  30. str_split(x[2],'///',simplify=T),
  31. sep = "...")
  32. })
  33. x = tibble(unlist(test_function))
  34. colnames(x) <- "ttt"
  35. ids <- separate(x,ttt,c("ID","Gene.Symbol"),sep = "\\...")
  36. dim(ids)
  37. #将Matrix格式表达矩阵转换为data.frame格式
  38. exprSet <- data.frame(expression_data)
  39. dim(exprSet)
  40. #给表达矩阵新增加一列ID
  41. exprSet$ID <- rownames(exprSet) # 得到表达矩阵,行名为ID,需要转换,新增一列
  42. dim(exprSet)
  43. #矩阵表达文件和平台文件有相同列'ID’,使用merge函数合并
  44. express <- merge(x = exprSet, y = ids, by.x = "ID")
  45. #删除探针ID列
  46. express$ID =NULL
  47. dim(express)
  48. matrix = express
  49. dim(matrix)
  50. #查看多少个基因重复了
  51. table(duplicated(matrix$Gene.Symbol))
  52. #把重复的Symbol取平均值
  53. matrix <- aggregate(.~Gene.Symbol, matrix, mean) ##把重复的Symbol取平均值
  54. row.names(matrix) <- matrix$Gene.Symbol #把行名命名为SYMBOL
  55. dim(matrix)
  56. matrix_na = na.omit(matrix) #去掉缺失值
  57. dim(matrix_na)
  58. matrix_final = matrix_na[matrix_na$Gene.Symbol != "",]
  59. dim(matrix_final)
  60. matrix_final <- subset(matrix_final, select = -1) #删除Symbol列(一般是第一列)
  61. dim(matrix_final)
  62. #+ 经过注释、探针名基因名处理、删除基因名为空值、删除缺失值 得到最终 matrix_final
  63. #+==================================================================================
  64. #+========================================================================================
  65. #+==================================================================================
  66. #+========================================================================================
  67. #+增加#(2)离群值处理
  68. #数据离群处理
  69. #处理极端值
  70. #定义向量极端值处理函数
  71. #用于处理异常值,将超出一定范围的值替换为中位数,以减少异常值对后续分析的影响。
  72. dljdz=function(x) {
  73. DOWNB=quantile(x,0.25)-1.5*(quantile(x,0.75)-quantile(x,0.25))
  74. UPB=quantile(x,0.75)+1.5*(quantile(x,0.75)-quantile(x,0.25))
  75. x[which(x<DOWNB)]=quantile(x,0.5)
  76. x[which(x>UPB)]=quantile(x,0.5)
  77. return(x)
  78. }
  79. #第一列设置为行名
  80. matrix_leave=matrix_final
  81. boxplot(matrix_leave,outline=FALSE, notch=T, las=2) ##出箱线图
  82. dim(matrix_leave)
  83. #处理离群值
  84. matrix_leave_res=apply(matrix_leave,2,dljdz)
  85. boxplot(matrix_leave_res,outline=FALSE, notch=T, las=2) ##出箱线图
  86. dim(matrix_leave_res)
  87. #+增加#(2)离群值处理
  88. #+==================================================================================
  89. #+========================================================================================
  90. #+==================================================================================
  91. #+========================================================================================
  92. #删除 低表达基因
  93. #仅去除在所有样本里表达量都为零的基因(平均值小于1)
  94. # 计算基因表达矩阵的平均值
  95. gene_avg <- apply(matrix_final, 1, mean)
  96. # 根据阈值筛选低表达基因
  97. filtered_genes_1 <- matrix_final[gene_avg >= 1, ] # 表达量平均值小于1的过滤
  98. dim(filtered_genes_1)
  99. #+================================
  100. #常用过滤标准2(推荐):
  101. #仅保留在一半以上样本里表达的基因
  102. # 计算基因表达矩阵每个基因的平均值
  103. gene_means <- rowMeans(matrix_final)
  104. # 计算基因平均值的排序百分位数
  105. gene_percentiles <- rank(gene_means) / length(gene_means)
  106. # 获取阈值
  107. threshold <- 0.25 # 删除后25%的阈值
  108. #threshold <- 0.5 # 删除后50%的阈值
  109. # 根据阈值筛选低表达基因
  110. filtered_genes_2 <- matrix_final[gene_percentiles > threshold, ]
  111. # 打印筛选后的基因表达矩阵
  112. dim(filtered_genes_2)
  113. boxplot(filtered_genes_2,outline=FALSE, notch=T, las=2) ##出箱线图
  114. #dim(filtered_genes)
  115. #+删除 低表达基因 得到filtered_genes_1 删除平均表达小于1的 得到filtered_genes_2 删除后25%的
  116. #+==================================================================================
  117. #+========================================================================================
  118. #+==================================================================================
  119. #+========================================================================================
  120. ### limma的函数归一化,矫正差异 ,表达矩阵自动log2化
  121. #1.归一化不是绝对必要的,但是推荐进行归一化。
  122. #有重复的样本中,应该不具备生物学意义的外部因素会影响单个样品的表达,
  123. #例如中第一批制备的样品会总体上表达高于第二批制备的样品,假设所有样品表达值的范围和分布都应当相似,
  124. #需要进行归一化来确保整个实验中每个样本的表达分布都相似。
  125. #2.归一化要在log2标准化之前做
  126. library(limma)
  127. exprSet=normalizeBetweenArrays(filtered_genes_2)
  128. boxplot(exprSet,outline=FALSE, notch=T, las=2) ##出箱线图
  129. ## 这步把矩阵转换为数据框很重要
  130. class(exprSet) ##注释:此时数据的格式是矩阵(Matrix)
  131. exprSet <- as.data.frame(exprSet)
  132. #标准化 表达矩阵自动log2化
  133. qx <- as.numeric(quantile(exprSet, c(0., 0.25, 0.5, 0.75, 0.99, 1.0), na.rm=T))
  134. LogC <- (qx[5] > 100) ||
  135. (qx[6]-qx[1] > 50 && qx[2] > 0) ||
  136. (qx[2] > 0 && qx[2] < 1 && qx[4] > 1 && qx[4] < 2)
  137. ## 开始判断
  138. if (LogC) {
  139. exprSet [which(exprSet <= 0)] <- NaN
  140. ## 取log2
  141. exprSet_clean <- log2(exprSet)
  142. print("log2 transform finished")
  143. }else{
  144. print("log2 transform not needed")
  145. }
  146. boxplot(exprSet_clean,outline=FALSE, notch=T, las=2) ##出箱线图
  147. ### limma的函数归一化,矫正差异 ,表达矩阵自动log2化 得到exprSet_clean
  148. #+==================================================================================
  149. #+========================================================================================
  150. # saving all data to the path
  151. save(exprSet_clean, file ="exprSet_clean_75percent_filter.RData")

上述处理得到了干净的基因表达矩阵,数据部分已经没有问题,但是在做数据挖掘(差异分析、富集分析等)之前还有一项准备工作,要将数据样本进行分组,即患病组、对照组

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多