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

Snakemake规则输出中能否使用含通配符的参数作为变量?

在Snakefile中用通配符定义参数并复用为输出路径的方法

想在Snakefile的规则里,用通配符定义params中的前缀,再把这个前缀参数复用在output的路径定义里,避免重复编写相同的路径前缀。尝试了如下写法:

rule train_stuff:
  input:
    "input.{lang}.txt"
  params:
    prefix="model.{lang}"
  output:
    "{params.prefix}.npz",
    "{params.prefix}.vocab",
    "{params.prefix}.some_other_auxiliary_output"
  shell:
    """
    # ... 生成三个输出文件的逻辑 ... 
    touch {output[0]}
    touch {output[1]}
    touch {output[2]}
    """

但这段代码会触发以下错误:

WildcardError in rule train_stuff in file (...)/Snakefile, line 2:
Wildcards in input files cannot be determined from output files:
'lang'

错误原因

报错的核心是Snakemake的依赖解析逻辑:它需要从输出路径的通配符反向推导输入路径的通配符。原写法中,输出路径用{params.prefix}包裹了前缀,导致Snakemake无法从输出路径里识别出lang这个通配符,自然没法对应到输入的input.{lang}.txt。

解决方案

方案1:用expand()函数简化输出路径定义

如果只是想避免重复写前缀,最简洁的方式是用expand()函数一次性生成所有输出文件,无需借助params:

rule train_stuff:
  input:
    "input.{lang}.txt"
  output:
    expand("model.{lang}.{ext}", ext=["npz", "vocab", "some_other_auxiliary_output"])
  shell:
    """
    # 直接用{output}批量引用所有输出文件
    touch {output}
    """

方案2:结合lambda函数与params复用前缀

如果确实需要通过params统一管理前缀(比如后续shell命令里也要复用),可以用lambda函数基于wildcards生成前缀,让Snakemake能识别输出中的通配符:

rule train_stuff:
  input:
    "input.{lang}.txt"
  params:
    # 用lambda从wildcards中获取lang生成前缀
    prefix=lambda wildcards: f"model.{wildcards.lang}"
  output:
    "{params.prefix}.npz",
    "{params.prefix}.vocab",
    "{params.prefix}.some_other_auxiliary_output"
  shell:
    """
    # shell中也可以直接复用params.prefix
    touch {params.prefix}.npz
    touch {params.prefix}.vocab
    touch {params.prefix}.some_other_auxiliary_output
    """

这里用lambda函数替代直接写"model.{lang}",让params的前缀动态依赖wildcards,Snakemake就能通过输出路径反向关联到输入的lang通配符,解决报错问题。

内容的提问来源于stack exchange,提问作者Jindra Helcl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:12:10