随机抽取一定比例的fastq文件

本文介绍两种从NGS产生的fq文件中抽取特定比例数据的方法。第一种方法通过随机选取读段实现快速处理,但存在一定随机误差;第二种方法确保精确抽取比例,但运行速度较慢。

在NGS的下机数据中,我们通常抽取一定比例的fq文件做分析。在此,笔者提供两种方式来抽取fq数据。


第一种方法速度较快,但存在一定的随机误差。

运行方式:

perl  $0 fq文件 抽取比例


#! /usr/bin/perl -w
use strict;
die "#usage:perl $0 <fq><threshold>\n" unless @ARGV==2;
my $fa=shift;
my $threshold=shift;
$fa=~/\.gz/?(open IN,"gzip -cd $fa|"||die) : (open IN,$fa||die);
while(<IN>){
	chomp;
	if($.%4==1){
		my $rand=rand(1);
		if($rand<$threshold){
			print "$_\n";
			print scalar <IN> for 1..3;
		}
	}
}
close IN;


第二种方法方法满足了精确抽取,但较第一种方法稍慢一些。用法相同。


#! /usr/bin/perl -w
use strict;
die "#usage:perl $0 <fq><threshold>\n" unless @ARGV==2;
my $fa=shift;
my $threshold=shift;
my $num=$fa=~/\.gz/? `gzip -cd $fa|wc -l`/4 :`less $fa|wc -l`/4;
my $need=int($num*$threshold);
my %ha;
for(;;){
	my $tmp=int(rand($num));
	$ha{$tmp}=1;
	last if (keys %ha)==$need; 
}
$fa=~/\.gz/?(open IN,"gzip -cd $fa|"||die) : (open IN,$fa||die);
while(<IN>){
	chomp;
	my $line=($.-1)/4;
	if(exists $ha{$line}){
		print "$_\n";
		print scalar <IN> for 1..3;
	}
}
close IN;



<think>我们已知单细胞测序数据通常以FASTQ文件形式存储原始测序读数(reads)。要从FASTQ文件中提特定细胞的数据,我们需要知道这些特定细胞的条形码(barcode)序列。因为每个细胞在测序前都被加上了一个独特的条形码,所以我们可以根据条形码来识别并提属于特定细胞的读数。 步骤概述: 1. 获目标细胞的条形码列表:通常,在单细胞测序数据分析的后期(例如,在聚类分析后),我们会得到每个细胞的聚类信息,同时每个细胞都有一个条形码。因此,我们可以根据聚类结果或其他细胞注释信息来确定我们感兴趣的细胞的条形码。 2. 准备一个包含这些目标条形码的文件(每行一个条形码)。 3. 使用工具(如grep、seqtk等)根据条形码从FASTQ文件中提读数。 具体步骤: 步骤1:获目标细胞的条形码 假设我们已经完成了单细胞数据的初步分析(例如,使用Cell Ranger、Seurat或Scanpy等工具),并得到了细胞的聚类结果。我们可以从聚类结果中提特定类群的细胞条形码。例如,在Seurat中,我们可以通过以下R代码提特定簇的细胞条形码: ```R # 假设seurat_object是已经完成聚类的Seurat对象 # 提聚类标签为1的细胞条形码 cluster1_barcodes <- WhichCells(seurat_object, idents = 1) # 将条形码写入文件 writeLines(cluster1_barcodes, "cluster1_barcodes.txt") ``` 步骤2:提特定条形码的读数 单细胞测序的FASTQ文件通常包含两个文件:一个包含测序读数(R1),另一个包含条形码和UMI(R2)。注意:不同实验方案可能不同,但10x Genomics的方案中,R1是测序读数,R2包含条形码和UMI。 然而,我们通常不会直接从原始FASTQ文件中提特定条形码的读数,因为原始FASTQ文件中的条形码可能包含错误,而且通常已经通过数据处理流程(如Cell Ranger)进行了校正。但如果我们确实需要从原始FASTQ文件中提,我们可以按照以下方法: 方法1:使用grep(适用于小文件) 由于FASTQ文件较大,使用grep可能效率不高,但可以尝试。注意:FASTQ文件中每四行为一个读数,其中条形码信息在R2文件的第一行(即每个读数的第二行)。但是,我们通常需要根据R2文件中的条形码来提对应的R1和R2的读数。 方法2:使用专门的工具,如seqtk、umitools等。 这里介绍使用seqtk的方法,但需要先根据条形码文件创建一个包含条形码和其反向互补的文件(因为测序时条形码可能是反向互补的,具体决于建库方式)。对于10x Genomics数据,R2中的条形码是原始序列(不需要反向互补),但要注意条形码在R2中的位置(通常为前16bp)。 我们可以使用以下脚本(使用seqtk的子命令subseq)来提: 首先,我们需要将条形码文件转换为一个列表,其中每个条形码占一行,然后使用seqtk提。 但是,seqtk subseq需要根据读数的名称来提,而我们的需求是根据序列内容(即条形码序列)来提。因此,我们可以使用以下步骤: 1. 从R2文件中提前16bp(假设条形码长度为16)作为该读数的名称的一部分,然后根据条形码列表进行匹配。 然而,更直接的方法是使用工具zumi-tools,它是专门处理UMI的工具,也可以根据条形码提读数。 方法3:使用umi_tools 安装umi_tools:`pip install umi_tools` 然后,使用以下命令提特定条形码的读数: ```bash umi_tools extract --bc-pattern=CCCCCCCCCCCCCCCC --stdin=raw_R2.fastq.gz --read2-in=raw_R1.fastq.gz --stdout=extracted_R1.fastq.gz --read2-stdout --filter-cell-barcode --whitelist=cluster1_barcodes.txt ``` 注意:--bc-pattern指定条形码的模式,这里用16个C表示16个碱基的条形码(实际模式根据实验设计,10x Genomics的v2/v3是16bp)。该命令会同时处理R1和R2,并输出提的R1和R2(通过--stdout输出R1,通过--read2-stdout输出R2,并合并到一个流,但我们可以用管道分开)。但是,umi_tools extract默认输出一个文件,我们可以用--stdout和--read2-stdout分别指定输出,但这里我们用一个命令同时输出两个文件可能比较麻烦。 另一种方法是使用bbsplit(来自BBTools套件)或samtools等工具,但需要先将FASTQ转换为BAM,然后根据条形码提。 考虑到用户可能希望用更简单的方法,这里介绍一个使用awk的方法(适用于小规模数据): 步骤: 1. 将R2文件解压(如果是gzip压缩的)。 2. 使用awk脚本匹配R2文件中的条形码(假设条形码在R2的第一行的1-16bp),如果匹配到白名单中的条形码,则输出该读数的名称,并同时输出该读数的四行(R2)以及对应的R1的四行。 但是,由于FASTQ文件很大,这种方法可能效率不高。 因此,对于大规模数据,建议使用专门的工具,如Cell Ranger的bamtofastq,但需要先有BAM文件。 实际上,Cell Ranger在处理原始数据时会产生一个BAM文件(包含比对结果和原始序列信息)。如果我们有这个BAM文件,那么提特定细胞的FASTQ文件会更方便。 方法4:从BAM文件(推荐,如果已有BAM文件) 步骤: 1. 从BAM文件中提特定条形码的读数,并转换为FASTQ。 我们可以使用samtools来提: ```bash samtools view -b -D CB:cluster1_barcodes.txt input.bam | samtools fastq - -1 extracted_R1.fastq -2 extracted_R2.fastq ``` 但是,注意:samtools的-D选项并不直接支持按细胞条形码(CB标签)过滤。我们可以使用更灵活的方法: 首先,将我们需要的条形码列表转换为一个标签文件(每行一个条形码),然后使用samtools的过滤表达式: ```bash samtools view -b -d CB:cluster1_barcodes.txt input.bam | samtools fastq - -1 extracted_R1.fastq -2 extracted_R2.fastq ``` 但是,samtools并不支持直接通过标签文件过滤。因此,我们可以使用awk来过滤: ```bash samtools view -h input.bam | awk -v barcode_file="cluster1_barcodes.txt" 'BEGIN { while (getline < barcode_file) { whitelist[$1]=1 } } /^@/ { print } $1!~/^@/ { if ($0 ~ /CB:Z:/) { split($0, a, "CB:Z:"); split(a[2], b, "\t"); cb = b[1]; if (cb in whitelist) { print } } }' | samtools view -bS - | samtools fastq - -1 extracted_R1.fastq -2 extracted_R2.fastq ``` 这个命令比较复杂,它做了以下事情: - 使用samtools view -h获BAM文件的头部和内容 - 使用awk:加载白名单条形码到数组whitelist;打印头部;对于非头部行,查找包含CB:Z:标签的行,并提条形码,如果该条形码在whitelist中,则打印该行。 - 然后通过管道传给samtools view -bS转换为BAM,再通过samtools fastq转换为FASTQ。 由于这种方法比较复杂,且需要BAM文件,所以如果用户没有BAM文件,可能需要先通过Cell Ranger等流程将FASTQ比对得到BAM。 考虑到用户可能没有BAM文件,我们回到从FASTQ的方法。这里推荐使用umi_tools,因为它可以直接处理FASTQ文件,并且效率较高。 因此,总结一下,如果用户有BAM文件,使用samtools和awk提是可行的。如果只有FASTQ文件,可以使用umi_tools。 注意:在umi_tools命令中,我们使用了--filter-cell-barcode和--whitelist,它会将条形码在白名单中的读数提出来,并且还会校正条形码(如果有一个碱基的错,可以校正到白名单中的条形码)。如果不希望校正,可以添加--error-correct-cell=false。 示例命令(详细): ```bash umi_tools extract --bc-pattern=CCCCCCCCCCCCCCCC --stdin=raw_R2.fastq.gz --read2-in=raw_R1.fastq.gz --stdout=extracted_R1.fastq.gz --read2-stdout | gzip > extracted_R2.fastq.gz ``` 但是,这个命令没有过滤条形码?实际上,我们需要添加--filter-cell-barcode和--whitelist。正确的命令如下: ```bash umi_tools extract --bc-pattern=CCCCCCCCCCCCCCCC --stdin=raw_R2.fastq.gz --read2-in=raw_R1.fastq.gz --stdout=extracted_R1.fastq.gz --read2-stdout --filter-cell-barcode --whitelist=cluster1_barcodes.txt | gzip > extracted_R2.fastq.gz ``` 然而,注意:--stdout输出的是R1,而--read2-stdout输出的是R2,但是它们会混合在同一个输出流中。因此,我们需要将R1和R2分开。我们可以使用一个技巧:将R1输出到文件,R2输出到另一个文件。但是,umi_tools extract不支持同时输出两个文件。因此,我们可以使用命名管道或者分两步。 另一种方式:使用--stdout和--read2-stdout,但是用tee命令分离?这比较复杂。 实际上,umi_tools extract的输出是混合的,它会在每一条读数的ID后面加上条形码和UMI信息,这样R1和R2的ID就不匹配了。所以,我们可能需要重新考虑。 根据umi_tools extract的文档,它默认将处理后的读数输出到一个文件,并且对于双端测序,它需要指定--read2-in和--read2-stdout,这样R1和R2会交错输出到标准输出。我们可以用awk来分离: ```bash umi_tools extract ... | awk '{ if (NR%8<=4) print > "extracted_R1.fastq"; else print > "extracted_R2.fastq" }' ``` 但是,这样写可能会因为缓冲问题出错,而且文件很大时效率低。 因此,建议使用两个不同的命令分别提R1和R2?但umi_tools extract是一次性处理双端的。 我们再看一下umi_tools extract的说明:它可以通过--stdout输出R1,通过--read2-stdout输出R2,但是这两个选项不能同时使用?实际上,--read2-stdout是当使用--stdout时,将R2输出到标准输出,而R1输出到--stdout指定的文件?文档说明: --stdout=STDOUT --read2-stdout 所以,如果我们指定--stdout=extracted_R1.fastq.gz,并且使用--read2-stdout,那么R2会输出到标准输出,我们可以重定向到文件: ```bash umi_tools extract --bc-pattern=CCCCCCCCCCCCCCCC --stdin=raw_R2.fastq.gz --read2-in=raw_R1.fastq.gz --stdout=extracted_R1.fastq.gz --read2-stdout --filter-cell-barcode --whitelist=cluster1_barcodes.txt > extracted_R2.fastq.gz ``` 这样,R1被写入extracted_R1.fastq.gz,R2被写入extracted_R2.fastq.gz。 注意:--stdin指定的是包含条形码的FASTQ(通常是R2),--read2-in指定的是测序读数的FASTQ(R1)。在10x Genomics中,R1是测序读数,R2是条形码和UMI,所以这里--stdin是R2,--read2-in是R1。 但是,在umi_tools中,它默认认为--stdin包含条形码,而--read2-in包含与条形码对应的读数(即基因表达序列,也就是R1)。所以这个命令是合理的。 另外,--bc-pattern需要根据实际实验设计来设置。10x Genomics v2/v3的条形码是16bp,所以是16个C。UMI是10bp或12bp(v3),所以模式可能是:CCCCCCCCCCCCCCCCNNNNNNNNNN(对于v2,UMI是10bp,所以后面10个N)。但是,在umi_tools中,我们只需要指定条形码部分,所以用16个C即可。 因此,完整的命令是: ```bash umi_tools extract --bc-pattern=CCCCCCCCCCCCCCCC --stdin=raw_R2.fastq.gz --read2-in=raw_R1.fastq.gz --stdout=extracted_R1.fastq.gz --read2-stdout --filter-cell-barcode --whitelist=cluster1_barcodes.txt > extracted_R2.fastq.gz ``` 注意:如果原始数据是多个文件(比如多个lane),需要先合并。 总结: 1. 准备目标细胞的条形码列表(每行一个,不带任何后缀,如“-1”等,注意与FASTQ中的条形码保持一致)。 2. 使用umi_tools extract命令,指定原始R1和R2文件,以及条形码列表,输出提后的R1和R2。 注意事项: - 确保条形码列表中的格式与FASTQ中的条形码序列一致(包括大小写,通常都是大写)。 - 如果条形码在R2中的位置不是从第一个碱基开始,需要调整--bc-pattern(例如,前面有固定序列,则用N表示可变,用固定序列表示固定部分,但这里10x Genomics的R2前16bp是条形码,所以直接16个C)。 - 如果使用其他单细胞技术,条形码的位置和长度可能不同,需要调整。 如果用户没有umi_tools,也可以考虑使用其他工具,如fastq-filter(来自fastq-tools)等,但需要自己编写脚本匹配条形码。 以上方法供用户参考。 引用说明: 在单细胞测序中,细胞的识别依赖于细胞条形码(barcode)[^1]。提特定细胞的数据需要先获得这些细胞的条形码列表[^2]。然后通过工具从FASTQ文件中提[^4]。由于FASTQ文件较大,推荐使用高效的工具如umi_tools[^4]。</think>要从单细胞测序数据的FASTQ文件中提特定细胞的数据,需要根据细胞条形码(barcode)进行筛选。以下是详细步骤和工具推荐: ### 一、核心原理 单细胞测序中,每个细胞通过**独特的细胞条形码**标记。原始FASTQ文件包含: - **R1文件**:基因序列读数 - **R2文件**:细胞条形码 + UMI(Unique Molecular Identifier) 提特定细胞数据的关键是**匹配目标细胞的条形码序列**。 ### 二、操作步骤 #### 1. 获目标细胞条形码 从分析结果中提目标细胞的条形码列表: ```r # Seurat示例:提聚类簇1的细胞条形码 library(Seurat) barcodes <- WhichCells(seurat_obj, idents = 1) writeLines(barcodes, "target_barcodes.txt") ``` #### 2. 使用工具提数据 推荐工具及方法: - **方法1:umi_tools(推荐)** ```bash umi_tools extract \ --bc-pattern=CCCCCCCCCCCCCCCC \ # 16bp条形码模式(10x Genomics) --stdin=raw_R2.fastq.gz \ # 含条形码的文件(R2) --read2-in=raw_R1.fastq.gz \ # 基因序列文件(R1) --stdout=extracted_R1.fastq.gz \ --read2-stdout \ --filter-cell-barcode \ --whitelist=target_barcodes.txt > extracted_R2.fastq.gz ``` 参数说明: - `--bc-pattern`:根据建库方案调整(如10x v3为16bp) - `--whitelist`:目标条形码文件 - 输出:`extracted_R1.fastq.gz`(基因序列),`extracted_R2.fastq.gz`(条形码+UMI) - **方法2:samtools + BAM文件(需先比对)** ```bash # 步骤1:FASTQ转BAM(需参考基因组) cellranger count --id=output --fastqs=fastq_dir --transcriptome=ref_genome # 步骤2:从BAM提特定细胞 samtools view -b -d CB:target_barcodes.txt possorted_genome_bam.bam | \ samtools fastq - -1 extracted_R1.fq -2 extracted_R2.fq ``` #### 3. 验证提结果 检查输出文件: ```bash zcat extracted_R1.fastq.gz | head -n 4 # 查看前4行 # 应包含目标条形码对应的序列 ``` ### 三、注意事项 1. **条形码格式**: - 确保FASTQ中的条形码格式与白名单一致(如是否含`-1`后缀) - 10x Genomics数据:条形码在R2文件的前16bp 2. **工具选择**: - 未比对数据:直接用`umi_tools`处理FASTQ - 已比对数据:从BAM提更高效[^4] 3. **错误容忍**: - 工具如`umi_tools`支持1bp错配校正(可通过`--error-correct-cell`启用) ### 四、典型应用场景 - 特定细胞亚群的基因表达验证 - 重新分析目标细胞群(如肿瘤细胞、免疫细胞) - 减少数据量以加速特定子集分析 > 关键参考:提依赖细胞条形码的精确匹配[^1],双端数据需同步处理R1/R2[^4],工具选择决于数据是否已比对[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值