You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Snakemake规则中如何通过script关键字条件性调用多个脚本

Snakemake规则中如何通过script关键字条件性调用多个脚本

我完全理解你的痛点——不想大改已经写好的Python和R脚本(毕竟它们都依赖snakemake.input这类变量),但又想在同一个Snakemake规则里根据条件额外运行R脚本。确实,Snakemake的script:关键字本身只支持指定单个脚本路径,没法直接写条件判断或者多个脚本,但有两个不用修改原有脚本的办法可以解决这个问题:

方法一:用snakemake --script在shell中调用多个脚本

Snakemake提供了--script命令行参数,它可以让你在shell环境中运行脚本,同时自动把当前规则的snakemake上下文(包括input、output、params等变量)注入到脚本里,这样你的原有脚本完全不用改动。

你只需要把规则改成用shell:关键字,先调用Python脚本,再根据条件调用R脚本:

rule merge_results:
    input:
        [...]  # 保持你的原有输入定义
    output:
        path_results  # 保持你的原有输出定义
    params:
        cond = your_condition  # 这里替换成你的实际条件,比如config["run_r_script"]或者某个输入是否存在
    shell:
        """
        # 先运行Python脚本,--script会自动传递snakemake上下文
        snakemake --script merge_results.py
        # 根据条件判断是否运行R脚本
        if {params.cond}; then
            snakemake --script my_script.R
        fi
        """

这个方案的好处是完全不用新增脚本,直接在规则里写shell逻辑就行,原有Python和R脚本的代码可以原封不动。

方法二:写一个轻量的Python调度脚本作为入口

如果更习惯用Python来处理逻辑,可以写一个简单的wrapper脚本,作为script:关键字的入口,在这个脚本里先执行原有Python脚本,再根据条件调用R脚本。

首先创建一个wrapper.py:

import subprocess
import sys

# 直接执行原有Python脚本,这样它能直接访问当前的snakemake对象
exec(open("merge_results.py").read())

# 根据条件判断是否运行R脚本,这里的cond从规则的params里获取
if snakemake.params.cond:
    # 调用R脚本,subprocess会继承当前环境变量,所以R脚本能拿到snakemake上下文
    subprocess.run(["Rscript", "my_script.R"], check=True, stderr=sys.stderr, stdout=sys.stdout)

然后修改你的规则:

rule merge_results:
    input:
        [...]
    output:
        path_results
    params:
        cond = your_condition
    script:
        "wrapper.py"

这个方案里,原有Python脚本通过exec直接在wrapper的上下文里运行,完全能访问snakemake变量;R脚本通过subprocess调用时,会继承wrapper的环境变量,而wrapper是作为Snakemake脚本运行的,所以R脚本里的snakemake包依然能正常读取到input、output等信息,不需要修改任何原有代码。

备注:内容来源于stack exchange,提问作者Kiffikiffe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:35:30