如何修改Snakemake脚本处理PE读段配置?解决通配符报错
为啥会报错?
这个错误的核心是你写的pastp_pe规则里,输出用了{sample1}和{sample2}两个不一样的通配符,Snakemake要求同一个规则的所有输出、日志文件必须用完全相同的通配符,不然没法保证每个任务的输出路径唯一,很容易出现多个任务往同一个文件里写的情况。另外你用expand分别处理R1和R2的列表,会生成所有R1和R2的乱组合(比如sample1的R1配sample2的R2),这完全不符合双端测序的配对逻辑。
怎么改?
我们要把样本名作为唯一的通配符,让每个样本的R1、R2一一对应,修改后的Snakefile如下:
import pandas as pd # 读配置文件,提取样本名,把每个样本的R1和R2对应起来 samples_df = pd.read_csv("config.txt", sep=' ', index_col=False) # 从forward文件名里抠出样本名(比如sample1_forward.fastq.gz → sample1) samples_df['sample'] = samples_df['forward'].str.split('_').str[0] # 转成字典,方便后续调用:key是样本名,value是对应的R1、R2文件名 samples = samples_df.set_index('sample').T.to_dict('list') rule all: # 告诉Snakemake最终要生成哪些文件,这是整个流程的目标 input: expand("trimmed/{sample}_forward.fastq", sample=samples_df['sample']), expand("trimmed/{sample}_reverse.fastq", sample=samples_df['sample']) rule fastp_pe: input: # 根据通配符{sample}找对应的R1和R2文件 read1=lambda wildcards: f"samples/{samples[wildcards.sample][0]}", read2=lambda wildcards: f"samples/{samples[wildcards.sample][1]}" output: trim_read1="trimmed/{sample}_forward.fastq", trim_read2="trimmed/{sample}_reverse.fastq" conda: "envs/fastp.yml" threads: 4 shell: """ fastp --thread {threads} -i {input.read1} -I {input.read2} -o {output.trim_read1} -O {output.trim_read2} """
改的核心思路
- 统一通配符:只用
{sample}这一个通配符贯穿输入输出,每个任务对应唯一的样本,不会出现路径冲突。 - 正确配对R1/R2:通过样本名把R1和R2绑定在一起,不会再生成乱配对的情况。
- 加rule all:明确告诉Snakemake最终要生成啥文件,不然它不知道从哪开始跑流程。
不用pandas的简化写法(适合样本少的情况)
要是不想用pandas,直接手动写样本和文件的对应关系也行:
# 直接定义每个样本的R1和R2 samples = { "sample1": ("sample1_forward.fastq.gz", "sample1_reverse.fastq.gz"), "sample2": ("sample2_forward.fastq.gz", "sample2_reverse.fastq.gz"), "sample3": ("sample3_forward.fastq.gz", "sample3_reverse.fastq.gz"), } rule all: input: expand("trimmed/{sample}_forward.fastq", sample=samples.keys()), expand("trimmed/{sample}_reverse.fastq", sample=samples.keys()) rule fastp_pe: input: read1=lambda wc: f"samples/{samples[wc.sample][0]}", read2=lambda wc: f"samples/{samples[wc.sample][1]}" output: "trimmed/{sample}_forward.fastq", "trimmed/{sample}_reverse.fastq" conda: "envs/fastp.yml" threads: 4 shell: "fastp --thread {threads} -i {input.read1} -I {input.read2} -o {output[0]} -O {output[1]}"
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

