Snakemake输入函数异常:带下划线文库名引发KeyError问题
解决Snakemake中带下划线Wildcard的KeyError问题
问题根源
你遇到的KeyError: '130241_1'是两个核心问题叠加导致的:
- Wildcard自动类型转换坑:Snakemake会优先尝试把wildcard解析为数字,而像
130241_1这种带下划线的字符串,会被它当成千位分隔符处理,直接解析成整数1302411。当你用这个整数去访问config['lib_input']时,它会转成字符串'1302411',但你的config里的key是'130241_1',自然匹配不上。 - 单引号格式不匹配:你提到输入样本带单引号但
lib_input的key缺失,这会进一步加剧匹配失败——如果实际样本名带单引号,而config里的key不带,两者完全无法对应。
解决方案
1. 强制Wildcard为字符串类型
要阻止Snakemake把library解析成数字,有两种实用方法:
方法一:在规则内添加Wildcard约束
修改findPeaks规则,用正则表达式限定library只能是包含下划线的字符串:
rule findPeaks: wildcard_constraints: library = r'[\w_]+' # 匹配字母、数字、下划线组成的字符串 input: sample = os.path.join(HOMERTAG_DIR, "{library}"), input = lambda wildcards: os.path.join(HOMERTAG_DIR, config['lib_input'][wildcards.library]) output: os.path.join(HOMERPEAK_DIR, "{library}.all.hpeaks") params: config['homer_findPeaks_params'] shell: "findPeaks {input.sample} -i {input.input} {params} -o {output}"
这个正则会强制Snakemake把library当作字符串处理,完整保留原始的130241_1格式。
方法二:全局设置Wildcard约束
如果多个规则都用到library wildcard,可以在Snakefile顶部全局声明,避免重复设置:
wildcard_constraints: library = r'[\w_]+'
2. 处理单引号匹配问题
根据你的实际情况调整:
- 如果实际样本名带单引号(比如
'130241_1')但config里的key不带,给wildcard添加前置单引号:input = lambda wildcards: os.path.join(HOMERTAG_DIR, config['lib_input'][f"'{wildcards.library}'"]) - 如果反过来,config里的key带单引号而wildcard不带,就去掉wildcard的单引号:
input = lambda wildcards: os.path.join(HOMERTAG_DIR, config['lib_input'][wildcards.library.strip("'")])
3. 检查Config格式
最后确认你的配置文件(比如config.yaml)里的lib_input key格式和wildcard完全一致。例如:
lib_input: 130241_1: path/to/input_sample1 130241_2: path/to/input_sample2
YAML中数字开头的字符串不需要加引号,会自动识别为字符串;如果key带特殊字符才需要用引号包裹。
验证测试
修改后先运行dry run验证:
snakemake -n findPeaks
如果没有再出现KeyError,说明问题已经解决。
内容的提问来源于stack exchange,提问作者RonicK
相关产品推荐
相关产品推荐

