Snakemake使用expand访问samples_dict报WildcardError问题求助
问题根因
你遇到的两类报错均源于同一个核心错误:Snakemake的路径模板字符串中,所有被{}包裹的内容都会被识别为通配符,不会直接解析为Python层的变量/字典。你直接在路径模板中嵌套{samples_dict[index]['date']}这类字典访问语法,会导致Snakemake把samples_dict当成未赋值的通配符,触发WildcardError;用双大括号转义时嵌套的括号结构混乱,就会触发格式字符串的单括号解析错误。
修复方案
1. 修正rule all的expand写法
不要在路径模板中嵌套字典访问,把需要的通配符值单独提取后通过zip参数按样本一一对应,避免生成不必要的笛卡尔积:
rule all: input: expand("../sample_{index}_date_{date}_{id}/Var/{id}_monitoring.vcf", index = samples_dict.keys(), date = [samples_dict[idx]['date'] for idx in samples_dict.keys()], id = [samples_dict[idx]['id'] for idx in samples_dict.keys()], zip)
2. 统一所有规则的路径模板
所有规则的输入输出路径模板中,仅保留独立通配符index、date、id,不要出现samples_dict、tumor_dict这类Python变量名:
以map_sort_index规则为例:
rule map_sort_index: input: f = lambda wildcards: combine_fastqs(f"sample_{wildcards.index}_date_{wildcards.date}_{wildcards.id}", "forward"), r = lambda wildcards: combine_fastqs(f"sample_{wildcards.index}_date_{wildcards.date}_{wildcards.id}", "reverse") output: bam = "../sample_{index}_date_{date}_{id}/{id}_before_dedup.bam", bai = "../sample_{index}_date_{date}_{id}/{id}_before_dedup.bam.bai" # 其余参数保持不变
3. 通过输入函数访问tumor_dict
需要用到tumor_dict的路径不要直接写在模板中,通过lambda输入函数在Python层完成查询:
以var_call规则为例:
rule var_call: input: chromsizes = config['chromsizes'], moni = lambda wildcards: f"../sample_{wildcards.index}_date_{wildcards.date}_{wildcards.id}/{tumor_dict[wildcards.id].strip()}.bed", bam = "../sample_{index}_date_{date}_{id}/{id}.bam", bai = "../sample_{index}_date_{date}_{id}/{id}.bam.bai" output: folder = directory("../sample_{index}_date_{date}_{id}/var"), bed = lambda wildcards: f"../sample_{wildcards.index}_date_{wildcards.date}_{wildcards.id}/{tumor_dict[wildcards.id].strip()}_extended_60.bed", vcf = "../sample_{index}_date_{date}_{id}/Var/{id}_monitoring.vcf" # 其余参数保持不变
注:这里加了strip()是因为你提供的tumor_dict值末尾有多余空格,避免路径拼接出错
其他注意事项
- 你原
dedup规则的shell命令中用到了不存在的输出变量{output.deduped},要改成{output.bam} - 不需要完全切换为纯Python脚本实现,Snakemake完全适配这种基于已有样本列表的流水线场景,只要将通配符模板和Python层的变量计算逻辑分开即可:路径模板仅定义通配符占位,所有字典查询、动态计算都放到Python层的expand参数、lambda函数中完成。
内容的提问来源于stack exchange,提问作者OhWeh
相关产品推荐
相关产品推荐

