在snakemake中使用expand()函数多次执行shell命令

时间:2019-10-01 15:07:15

标签: snakemake

我想借助snakemake在不同的输入文件上多次执行R脚本。为此,我尝试使用expand函数。

我对snakemake还是比较陌生,当我正确理解它时,expand函数会为我提供例如多个输入文件,然后将它们全部连接起来并可以通过{input}使用。

是否可以一一调用文件上的shell命令?

可以说我在config.yaml中有这个定义:

types:
    - "A"
    - "B" 

这是我的示例规则:

rule manual_groups:
    input:
        expand("chip_{type}.bed",type=config["types"])
    output:
        expand("data/p_chip_{type}.model",type=config["types"])
    shell:
        "Rscript scripts/pre_process.R {input}"

这将导致命令:

Rscript scripts/pre_process.R chip_A.bed chip_B.bed

是否有可能改为使用以下两种类型分别两次调用命令:

Rscript scripts/pre_process.R chip_A.bed
Rscript scripts/pre_process.R chip_B.bed

谢谢您的帮助!

2 个答案:

答案 0 :(得分:2)

rule all中定义final target files,然后在规则type中使用适当的通配符(即manual_groups)。这将为rule manual_groups中列出的每个输出文件分别运行rule all

rule all:
    input:
        expand("data/p_chip_{type}.model",type=config["types"])


rule manual_groups:
    input:
        "chip_{type}.bed"
    output:
        "data/p_chip_{type}.model"
    shell:
        "Rscript scripts/pre_process.R {input}"

PS-由于与Python的type方法可能存在冲突,因此您可能需要更改通配符术语type

答案 1 :(得分:0)

我会同意@ManavalanGajapathy的回答,即这是解决您的问题的最可靠的解决方案。但是,这不是一个完整的答案。

expand只是Snakemake中定义的常规Python函数。这意味着您可以在使用Python的任何地方使用它。它只是一个实用程序,它接受字符串和参数进行替换,并返回字符串列表,其中每个字符串都是单个替换的结果。该实用程序可以在许多地方使用。在下面,我提供了一个说明这个想法的漂亮示例。假设您需要将一个文本文件作为输入并替换一些字符(该列表应从config中提供)。想象一下,您知道唯一的方法:作为sed脚本的管道。像这样:

cat input.txt | sed 's/A/a/g' | sed 's/B/b/g' | sed 's/C/c/g' > output.txt

您得出的结论是,您需要对一系列sed命令进行流水处理,这两个符号不同:sed's / X / x / g'。这是使用expand函数的解决方案:

rule substitute:
    input: "input.txt"
    output: "output.txt"
    params:
       from = ["A", "B", "C"],
       to = ["a", "b", "c"]
    shell: "cat {input} | " + " | ".join(expand("sed 's/{from}/{to}/g'", zip, from=params.from, to=params.to)) + " > {output}"