Snakemake中使用expand按变量分组拼接子目录tab文件方法
问题根因
cat规则的输入块中,expand同时传入gene=GENES、sample=SAMPLES两个遍历参数,会在工作流解析阶段直接展开为所有基因、所有样本的全量文件集合,和输出路径中的{gene}通配符完全没有绑定关系。无论当前规则要生成BOB还是LISA的结果,输入都会包含两个基因目录下的全部.tab文件,必然出现跨基因混合拼接的问题。
另外原shell逻辑中awk命令仅读取{input[0]}即第一个输入文件,本身也无法实现多文件拼接的效果。
修改方法
调整输入展开逻辑,仅在样本维度做expand,基因维度交给Snakemake的通配符机制自动匹配当前规则实例对应的基因值,同时修正shell命令的输入参数:
- 移除
expand中的gene=GENES参数,保留路径中的{gene}通配符占位,让expand仅展开当前匹配基因下的所有样本文件 - 将awk命令中的
{input[0]}替换为{input},传入所有待拼接的样本文件
修改后的完整可运行代码如下:
GENES=["BOB","LISA"] SAMPLES=["FB_399","FB_400"] rule all: input: expand("/path/to/{gene}/ALL_final.tab", gene=GENES) # 其余生成单个.annotation.tab文件的规则保持原有逻辑即可 rule cat: input: expand("/path/to/{gene}/{sample}.annotation.tab", sample=SAMPLES) output: temp("/path/to/{gene}/all.tab"), "/path/to/{gene}/ALL_final.tab" shell: """ awk 'FNR > 1 {{print FILENAME "\t" $0}}' {input} > {output[0]} sed -i 's/.annotation.tab//g' {output[0]} cat header.txt {output[0]} > {output[1]} """
修改后逻辑:当Snakemake调度生成BOB目录下的结果时,{gene}通配符自动取值为BOB,输入仅会加载BOB目录下两个样本的annotation文件;调度生成LISA的结果时同理,仅加载LISA目录下的对应文件,不会出现跨基因混合的问题。
如果后续存在不同基因对应不同样本列表的场景,可以将input替换为lambda函数动态获取对应基因的文件列表,当前全样本共有的场景下上述写法已经满足需求。
内容的提问来源于stack exchange,提问作者user3224522
相关产品推荐
相关产品推荐

