如何从在 snakemake 中不共享命名约定的单个输入文件生成多个输出文件?

How to generate multiple output files from single input file that does not share naming convention in snakemake?

我已经搜索了一段时间, 线程是我找到的最接近的线程,但无法使用我的设置。

我想做的事情:

我有一个文本文件,其中每一行都有一个 ID 和一个数据点

1234 data2
5678 data3
...

我想收集配置文件中与某些 ID 对应的行,并将它们写入根据 ID 值(1234 或 5678)命名的自己的文件中

# config.yaml
IDs:
    ID1: 1234
    ID2: 5678

当我在没有 snakemake 的情况下执行此操作时,我只是遍历 bash 脚本中的 ID 列表并为它们搜索文本文件,但我无法使用 snakemake 完成此操作。

要么我在目标中遇到通配符问题,要么我的扩展函数将所有 ID 提供给 shell 中的 grep 命令,或者在遵循接受的链接答案时,我得到“缺少输入文件统治一切:And_Laa A_log" 我可以分享我现在拥有的,但我认为正确的方法与我所拥有的相去甚远,这只会让每个人感到困惑:

configfile: "config.yaml"

# Trying to replicate Whosebug answer
speakers = {
  "1": "And_Laa",
  "2": "A_log"
}

def get_speaker(wildcards):
#  return expand("{speaker}", speaker=config["speakers"]) 
  return speakers[wildcards.speaker]

rule all:
  input:
#    expand("{speaker}_wav-list", speaker=config[speakers])
    expand("{speaker}", speaker=speakers.values())

# Selecting all the audiofiles for the speakers from a very large file
rule select_speaker_files:
  input:
    wav=config["files"]["wavs"]
  output:
    speaker="{speaker}_wav-list"
  params:
    speaker=get_speaker,
  shell:
    'grep "{params.speaker}" {input.wav} > {output.speaker}'

首先,我猜你所说的“speaker”不是dict的值,而是key。所以你 rule all 应该这样展开:

rule all:
  input:
    expand("{speaker}", speaker=speakers)

接下来,这条规则的字面意思是:“我需要两个文件名分别为 12 的文件。”但是没有规则可以生成具有这些名称的文件。你有:

rule select_speaker_files:
  output:
    speaker="{speaker}_wav-list"

他们的规则声称:“我可以生成一个名称以 _wav-list 结尾的文件。”绝对没有规则可以产生管道需要创建的东西。你的意思可能是:

rule all:
  input:
    expand("{speaker}_wav-list", speaker=speakers)

在这种情况下,规则至少是一致的。