如何在Snakemake中配置多级目录匹配,保留lane与样本标识
问题核心原因
glob_wildcards会分别返回所有匹配到的lane和sample列表,expand()默认对传入的多组通配符做笛卡尔积组合,所以会生成大量不存在的lane+sample组合路径。
解决方案
通过成对匹配真实存在的(lane, sample)组合,配合expand的zip参数实现一一对应,避免全量组合:
步骤1:获取真实存在的lane-sample配对
# 该方法返回的两个列表按位置一一对应,均为实际存在的路径组合 lane_list, sample_list = glob_wildcards('path/to/MyFolder/{lane}/{sample}/Aligned.out.sam')
步骤2:修改rule all的input逻辑
给expand添加zip参数,让lane和sample按位置配对生成目标路径:
rule all: input: expand('logs/fastqc/{lane}/{sample}.log', zip, lane=lane_list, sample=sample_list)
步骤3:补全fastqc规则的输入配置
原规则缺少输入SAM文件的声明,补充即可:
rule fastqc: input: 'path/to/MyFolder/{lane}/{sample}/Aligned.out.sam' output: html='/fastqc/{lane}/{sample}.html', zip='/fastqc/{lane}/{sample}_fastqc.zip' threads: 1 log: 'logs/fastqc/{lane}/{sample}.log' resources: mem_mb=8000, cpus=1 wrapper: '0.77.0/bio/fastqc'
后续合并SAM的扩展实现
如果需要按样本合并不同lane的SAM文件,可以先构建样本到所属lane的映射,再编写合并规则:
from collections import defaultdict # 构建样本-对应lane列表的映射 sample_to_lanes = defaultdict(list) for lane, sample in zip(lane_list, sample_list): sample_to_lanes[sample].append(lane) rule merge_sample_sam: input: lambda wildcards: [f'path/to/MyFolder/{lane}/{wildcards.sample}/Aligned.out.sam' for lane in sample_to_lanes[wildcards.sample]] output: 'merged_sam/{sample}.merged.sam' threads: 4 resources: mem_mb=16000 shell: 'samtools merge -@ {threads} {output} {input}'
内容的提问来源于stack exchange,提问作者Shashank Nagaraja
相关产品推荐
相关产品推荐

