我想借助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
谢谢您的帮助!
答案 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}"