【问题标题】:Using multiple filenames as wildcards in Snakemake在 Snakemake 中使用多个文件名作为通配符
【发布时间】:2018-01-25 13:03:54
【问题描述】:

我正在尝试创建一个规则来在snakemake 中实现bedtools,这将closest 一个文件与另一个目录中的一堆文件。

我有的是,在/home/bedfiles目录下,20个床位文件:

1A.bed , 2B_83.bed , 3f_33.bed ...

我想要的是,/home/bedfiles目录下,20个修改过的床文件:

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 目录中生成带有_modified 扩展名的文件。

我想用Snakemake 来实现它,但是我一直遇到语法错误,我不知道如何修复。我的试验是:

Step1:获取目录下的第一部分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

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} """

它在规则所有输入的行抛出错误:

invalid syntax

你知道如何克服这个错误或任何其他方式来实现它吗?

PS : 无法一一写出文件名。

【问题讨论】:

    标签: input wildcard snakemake


    【解决方案1】:

    inputclosest 中的outputoutput 定义中删除对expand 的调用。您目前正在传递一个包含 20 个文件名的向量作为 input.input2 和一个包含 20 个文件名的向量作为 output

    也就是说,您的规则closest 当前正在尝试运行一次并创建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 运行它。 Snakemake是目标导向的;它解决了如何根据现有文件制作所需的输出。

    【讨论】:

    • 但是,如果我不展开,如何在 rule all 中指定输出名称?
    • 另外,当我说 /path/to/bedfiles/{prefix}.bed 时,我在哪里指定这个前缀?是在 bash 中说 *.bed 吗?
    • 我没有说要修改rule all,保持扩展在那里。 prefix 是自动定义的,因为输入 .bed 和输出 _modified 文件位于同一目录中。 Snakemake 将查看all::input 中的文件名,并根据现有文件和定义的规则确定如何制作每个文件名。例如,通过自动将prefix 设置为“/home/bedfiles/1A”,可以使用规则closest 从“/home/bedfiles/1A.bed”生成“/home/bedfiles/1A_modified” .
    • 那么我也应该删除 FIRSTPART 变量吗?
    • 感谢您的回复。我错过了 input_files 的声明,因此我无法获取正确的床文件。这是一个很好的答案!再次感谢!
    【解决方案2】:

    简单一:无效语法是指input1 = "/home/other/merged.txt"后面缺少的, 希望能帮助到你 马克

    【讨论】:

    • @bapors 我认为 snakemake 有时会抛出错误,报告规则开始的行。但也许不是因为语法错误...
    • 我认为这不应该被否决,原始帖子中存在真正的语法错误
    猜你喜欢
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 2022-08-06
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多