Input 在Snakemake中使用多个文件名作为通配符
我正在尝试创建一个规则来实现Input 在Snakemake中使用多个文件名作为通配符,input,wildcard,snakemake,Input,Wildcard,Snakemake,我正在尝试创建一个规则来实现snakemake中的bedtools,该规则将与另一个目录中包含大量文件的文件最接近 在/home/bedfiles目录下,我有20个bed文件: 1A.bed , 2B_83.bed , 3f_33.bed ... 1A_modified, 2B_83_modified , 3f_33_modified ... 我想要的是,在/home/bedfiles目录下,有20个修改过的bed文件: 1A.bed , 2B_83.bed , 3f_33.bed ...
snakemake
中的bedtools
,该规则将与另一个目录中包含大量文件的文件最接近
在/home/bedfiles
目录下,我有20个bed文件:
1A.bed , 2B_83.bed , 3f_33.bed ...
1A_modified, 2B_83_modified , 3f_33_modified ...
我想要的是,在/home/bedfiles
目录下,有20个修改过的bed文件:
1A.bed , 2B_83.bed , 3f_33.bed ...
1A_modified, 2B_83_modified , 3f_33_modified ...
所以bash命令应该是:
filelist='/home/bedfiles/*.bed'
for mfile in $filelist;
do
bedtools closest -a /home/other/merged.txt -b ${mfile} > ${mfile}_modified
因此,此命令将在/home/bedfiles
目录中修改扩展名为\u的文件
我想用Snakemake
实现这一点,但是我一直有一个语法错误,我不知道如何修复。我的审判是:
步骤1:获取目录中bed文件的第一部分
FIRSTPART = [f.split(".")[0] for f in os.listdir("/home/bedfiles") if f.endswith('.bed')]
步骤2:定义输出名称和文件夹
MODIFIED = expand("/home/bedfiles/{first}_modified", first=FIRSTPART)
第三步:在规则中写入此内容
rule all:
input: MODIFIED
步骤4:制定具体规则以实施“最接近的床上工具”
rule closest:
input:
input1 = "/home/other/merged.txt" , \
input2 = expand("/home/bedfiles/{first}.bed", first=FIRSTPART)
output:
expand("/home/bedfiles/{first}_modified", first=FIRSTPART)
shell:
""" bedtools closest -a {input.input1} -b {input.input2} > {output} """
它在规则all的行中抛出错误,输入:
invalid syntax
您是否知道如何克服此错误或以任何其他方式实现它
PS:无法逐个写入文件名。简单:无效语法指的是,input1=“/home/other/merged.txt”
希望能有帮助
Marc删除对输入定义中的展开
和输出定义中的最近
的调用。您当前正在将20个文件名的向量作为input.input2
传递,将20个文件名的向量作为output
传递
也就是说,您的规则最近的
当前正在尝试运行一次并创建20个文件;而它应该运行20次,每次创建一个文件
在closest
中,每次运行该规则时,您都希望input.input2
成为单个文件,而output
成为单个文件:
FIRSTPART = [f.split(".")[0] for f in os.listdir("/home/bedfiles") if f.endswith('.bed')]
print("These are the input files:")
print([f + ".bed" for f in FIRSTPART])
MODIFIED = expand("/home/bedfiles/{first}_modified", first=FIRSTPART)
print("These will be created")
print(MODIFIED)
rule all:
input: MODIFIED
rule closest:
message: """
Converts /home/other/merged.txt and /some/dir/xyz.bed
into /some/dir/xyz_modified
"""
input:
input1 = "/home/other/merged.txt",
input2 = "{prefix}.bed"
output: "{prefix}_modified"
shell:
"""
bedtools closest -a {input.input1} -b {input.input2} > {output}
"""
下面是一个实验:
将自己移动到临时目录中,并在该目录中执行以下操作:
mkdir bedfiles
touch bedfiles/{a,b,c,d}.bed
然后将名为Snakefile
的文件添加到包含以下代码的当前目录中
import os
import os.path
import re
input_dir = "bedfiles"
input_files = [os.path.join(input_dir, f) for f in os.listdir(input_dir)]
print(input_files)
output_files = [re.sub(".bed$", "_modified", f) for f in input_files]
print(output_files)
rule all:
input: output_files
rule mover:
input: "{prefix}.bed"
output: "{prefix}_modified"
shell:
""" cp {input} {output} """
然后在命令行中使用snakemake
运行它。蛇行是以目标为导向的;它解决了如何根据现有文件生成所需的输出。但是,如果我不展开,如何在规则all中指定输出名称?另外,当我说/path/to/bedfiles/{prefix}.bed时,我在哪里指定这个前缀?在bash中是说*.bed吗?我没有说要修改规则all
,将扩展保持在那里。由于输入.bed
和输出\u修改的文件位于同一目录中,因此会自动定义前缀。Snakemake将查看all::input
中的文件名,并根据现有文件和定义的规则确定如何创建每个文件名。例如,通过自动将前缀设置为“/home/bedfiles/1A”,可以使用规则最接近的从“/home/bedfiles/1A.bed”生成“/home/bedfiles/1A_modified”。那么我是否也应该删除第一部分变量?感谢您扩展您的答复。我缺少输入文件的声明,因此无法绘制正确的床文件。这是一个极好的答案!再次感谢你@我认为snakemake有时会在报告规则开始的行时抛出错误。但可能不是因为语法错误……我认为这不应该被否决,在最初的帖子中有一个真正的语法错误