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


    检索到目标数据集后,开始数据挖掘,本文以阿尔兹海默症数据集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")

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

  • 相关阅读:
    一文看懂推荐系统:物品冷启02:简单的召回通道
    【python版CV】- 银行卡号识别项目
    Codeforcess834
    Chromium 开发指南2024 Mac篇-开始编译Chromium(五)
    虹科活动 | 探索全新AR应用时代,虹科AR VIP研讨会广州场回顾!
    测量工具----示波器
    关联容器(字典)map
    MYSQL CONCAT函数
    第3章 初识SqlSugarCore之ConfigureOptions注入实现
    DPDK代码目录结构
  • 原文地址:https://blog.csdn.net/zzh1464501547/article/details/133326080