生信数据去重不再难:R脚本+零代码平台,手把手教你搞定

在转录组、蛋白组、代谢组等高通量数据分析中,原始数据常因测序冗余、样本合并、数据库合并等原因出现重复记录。例如,基因表达矩阵中同一基因多次出现,会导致后续差异分析、聚类结果偏差。按指定列去除重复行是最常用的数据清洗操作之一。本文将从原理到实战,为你提供两种解决方案:

  1. R语言脚本(序动实验平台粘贴完整代码+逐句解析,适合想学编程的你)
  2. 零代码云平台(翰佰尔HiOmics ,一键出结果)

一、R脚本完整展示(带逐行中文注释)

以下脚本已针对单机环境优化,输入输出路径可自定义。每行代码均有中文注释,小白也能看懂。

# -----------------------------------------------------------------------------

# 数据去重脚本(单机版)

# 更多R语言交流可以和我们联系https://henbio.com/tools

# 功能:读取制表符分隔的文本文件(带表头),按指定列去除重复行,输出结果

# -----------------------------------------------------------------------------


# 加载 rlang 套件

library(rlang)

# 加载 dplyr 包

library(dplyr)

# 加载 readr 包

library(readr)


# ---------- 用户自定义参数(请根据实际需求修改)----------


# 设置工作目录(确保路径存在,若不存在则创建)

# dir.create("/home/bio/R/RCourse/", recursive = TRUE)

# setwd("/home/bio/R/RCourse/")

# dir.create("C:/Users/Administrator/Documents/RCourse", recursive = TRUE)

setwd("C:/Users/Administrator/Documents/RCourse")


# 获取当前工作目录路径(用于后续拼接输入/输出文件)

inputPath <- getwd()


# 输入文件完整路径(制表符分隔的 txt,第一行为列名)

inputFile <- paste0(inputPath, "/input.txt")


# 指定去重依据的列号(从 1 开始计数,例如第 8 列)

r_clunm <- 8


# ---------- 读取输入文件 ----------


# 提取文件基本名,分割后缀(例如 "input.txt" -> "input" 和 "txt")

file_suffix <- strsplit(basename(inputFile), "\\.")[[1]]

# 取最后一个元素作为文件后缀,并转为小写(便于统一判断)

filetype <- tolower(tail(file_suffix, 1))


# 自动生成输出文件名:Remove_Duplicates_列号.后缀(例如 Remove_Duplicates8.txt)

outputFileName <- paste0(inputPath, "/Remove_Duplicates", r_clunm, ".", filetype)


# 使用 readr 包的 guess_encoding 函数猜测文件编码(前 1000 字节)

encode <- guess_encoding(inputFile, n_max = 1000)[1, 1, drop = TRUE]

# 若无法识别编码,则终止程序并报错

if (is.na(encode)) {

  stop(paste("[ERROR] 无法识别文件编码:", inputFile))

}


# 根据文件类型选择相应的读取方式

if (filetype %in% c("csv", "txt")) {

 

  # 定义内部函数:读取 CSV 或 TXT 文件(支持编码回退)

  read_data <- function(filename, has_header) {

   

    if (filetype == "csv") {

      # 尝试用猜测的编码读取 CSV,若警告则回退到 UTF-8-BOM

      df <- tryCatch(

        read.csv(filename, header = has_header, fileEncoding = encode,

                 sep = ",", check.names = FALSE, fill = TRUE, na.string = ""),

        warning = function(e) {

          read.csv(filename, header = has_header, fileEncoding = "UTF-8-BOM",

                   sep = ",", check.names = FALSE, fill = TRUE, na.string = "")

        }

      )

    } else if (filetype == "txt") {

      # 尝试用猜测的编码读取 TXT(制表符分隔),若警告则回退到 UTF-8-BOM

      df <- tryCatch(

        read.table(filename, header = has_header, fileEncoding = encode,

                   sep = "\t", check.names = FALSE, fill = TRUE, na.string = ""),

        warning = function(e) {

          read.table(filename, header = has_header, fileEncoding = "UTF-8-BOM",

                     sep = "\t", check.names = FALSE, fill = TRUE, na.string = "")

        }

      )

    }

    return(df)

  }

 

  # 调用读取函数,传入输入文件和表头标志(第一行为列名)

  data <- read_data(inputFile, has_header = TRUE)

 

} else if (filetype %in% c("xls", "xlsx")) {

 

  # 定义内部函数:读取 Excel 文件(需安装 readxl 包)

  read_data <- function(filename, has_header) {

    # 使用 readxl::read_excel 读取,col_names 控制是否将第一行作为列名

    df <- readxl::read_excel(filename, col_names = has_header)

    # 转换为标准 data.frame 格式(read_excel 返回 tibble)

    return(as.data.frame(df))

  }

 

  # 调用读取函数

  data <- read_data(inputFile, has_header = TRUE)

 

} else {

  # 不支持的文件格式,报错退出

  stop("[ERROR] 仅支持 txt / csv / xls / xlsx 格式")

}


# ---------- 按指定列去重复 ----------


# duplicated() 返回逻辑向量:TRUE 表示该行在指定列上重复(第二次及以后出现)

# 取反 (!) 后保留首次出现的行(即重复项只保留第一条)

data <- data[!duplicated(data[, r_clunm], fromLast = FALSE), ]


# ---------- 输出结果到文件 ----------


# 将去重后的数据框写入制表符分隔的文本文件

write.table(data, file = outputFileName,

            sep = "\t",             # 列分隔符为制表符

            row.names = FALSE,      # 不输出行名

            quote = FALSE)          # 字符串不加引号


# 在控制台打印成功信息,提示用户结果保存位置

cat("去重完成,结果已保存至:", outputFileName, "\n")

二、逐句语法解析——核心代码深度拆解

1. 参数设置区

r_clunm <- 8
  • 语法:<-赋值,数字8表示去重依据的列号(从1开始)。
  • 作用:这是整个脚本的灵魂参数。修改它即可控制按哪一列去重,从而得到截然不同的结果。

2. 编码自动检测

encode <- guess_encoding(inputFile, n_max = 1000)[1, 1, drop = TRUE]
  • 语法:guess_encoding()来自 readr包,读取前1000字节推测编码;[1,1,drop=TRUE]提取第一个编码名。
  • 作用:自动识别UTF-8、GBK等编码,避免中文乱码。生信数据常来自Windows(GBK),此功能非常实用。

3. 文件读取与容错

df <- tryCatch(

  read.table(...),

  warning = function(e) { read.table(..., fileEncoding = "UTF-8-BOM") }

)
  • 语法:tryCatch()捕获警告(warning),当首次读取因编码问题产生警告时,自动改用 UTF-8-BOM编码重试。
  • 作用:提高脚本鲁棒性,即使文件编码不规范也能正常读取。

4. 核心去重语句

data <- data[!duplicated(data[, r_clunm], fromLast = FALSE), ]
  • 语法
    • duplicated(x):返回逻辑向量,标记x中每个元素是否为重复(第一次出现为FALSE,之后为TRUE)。
    • !duplicated(...):取反,得到非重复行的索引。
    • data[逻辑向量, ]:按行筛选,保留所有非重复行。
  • 参数:fromLast = FALSE表示保留第一次出现的行;若改为 TRUE则保留最后一次出现的行。
  • 作用:一行代码完成去重,简洁高效。

5. 输出文件

write.table(data, file = outputFileName, sep = "\t", row.names = FALSE, quote = FALSE)
  • 语法:sep="\t"制表符分隔;row.names=FALSE不输出行名;quote=FALSE不加引号。
  • 作用:输出与输入格式一致的纯文本文件,方便后续分析。

三、参数对结果的影响——对比实验

我们用同一份 input.txt(包含30多个基因,其中 gene030出现三次)分别按第1、2、6、8列去重,观察结果差异。

示例文件下载 https://henbio.com/tooldetail?id=93

示例数据片段(input.txt

geneID

sample1

sample2

...

sample8

gene001

1

0

...

0

gene002

2

0

...

0

...

...

...

...

...

gene030

31

3

...

6

gene030

30

0

...

0

gene030

0

0

...

0

实验结果对比

去重列

保留行数

典型应用场景

1 (geneID)

31

去除基因名重复,保留每个基因的第一条表达谱

2 (sample1)

31

sample1值几乎唯一,结果与按第1列类似

6 (sample5)

1

6列绝大部分为0,导致几乎所有行被视为重复

8 (sample7)

1

同上,第8列也几乎全0

关键启示

  • 去重列必须具有足够的信息量。如果某列90%以上的值相同,去重后会丢失大量有效数据。
  • 通常按基因ID(第1列)去重最符合生物学意义;按数值列去重风险极大,可能导致数据灾难性丢失。
  • 排序决定保留哪一行。本脚本默认保留第一次出现的行。如果想保留表达量最高的行,可先按表达值降序排序,再去重。

四、使用方法(三步走)

步骤1:准备输入文件

  • 必须是制表符分隔的.txt文件,第一行为列名。
  • 文件名和路径不能包含中文、空格
  • 示例格式见上表。

步骤2:修改参数

  • 将 setwd()内的路径改为你的工作目录。
  • 将 inputFile指向你的输入文件。
  • 将 r_clunm设为要去重的列号(如1)。

步骤3:运行脚本

  • 在RStudio中选中全部代码,点击 Run,或使用 source("脚本路径.R")。
  • 输出文件位于工作目录下,名为 Remove_DuplicatesX.txt(X为列号)。

五、零代码方案——不用写代码也能去重

方案1:翰佰尔 HiOmics 云平台(强烈推荐)

👉 https://henbio.com/tooldetail?id=93

  • 上传 .txt文件(制表符分隔)
  • 设置“指定列”(输入列号)
  • 点击运行,几秒后即可下载结果
  • 内置示例数据,可先测试再上传自己的数据

方案2:序动实验平台(适合教学)

👉 http://platform.omicsflowlab.com/#/InternshipTools

  • 提供R语言基础教学模块
  • 可直接在线编辑和运行R代码,无需本地安装
  • 适合想学习R但又不想配置环境的同学

六、在生信分析中的典型应用

  1. 基因表达矩阵去重:多个探针映射到同一基因时,只保留一个代表值(平均值或最大值)。
  2. 变异位点去重:VCF文件中同一染色体位置有多条记录,按染色体+位置去重。
  3. 样本元数据去重:合并多个批次数据时,去除重复的样本ID。
  4. GO/KEGG富集结果去重:不同通路共享同一组基因时,按通路去冗余。

七、总结

数据去重是生信分析的基石操作,看似简单却容易踩坑。本文提供的R脚本经过生产环境验证,注释详尽,参数灵活。如果你追求效率,翰佰尔平台的一键去重功能更是省时省力。无论选择哪种方式,请记住:去重前务必确认去重列的含义,避免误删重要数据


参考文献

  • Li W, Zhang Z, Xie B, et al. HiOmics: A cloud-based one-stop platform for the comprehensive analysis of large-scale omics data. Comput Struct Biotechnol J. 2024;23:659-668.
  • Zhang ZN, Tang YY, He YL, et al. HiOmics 2.0: An All-in-One Intelligent Cloud Platform for Multi-Omics Analysis in Biomedical Research. iCell. 2025 Dec 31;2(3).

Logo

一站式 AI 云服务平台

更多推荐