Snakemake输入两个变量输出一个变量

Snakemake input two variables and output one variable

我想重命名并移动我的 fastq.gz 文件:

NAME-BOB_S1_L001_R1_001.fastq.gz
NAME-BOB_S1_L001_R2_001.fastq.gz
NAME-JOHN_S2_L001_R1_001.fastq.gz
NAME-JOHN_S2_L001_R2_001.fastq.gz

这些:

NAME_BOB/reads/NAME_BOB.R1.fastq.gz
NAME_BOB/reads/NAME_BOB.R2.fastq.gz
NAME_JOHN/reads/NAME_JOHN.R1.fastq.gz
NAME_JOHN/reads/NAME_JOHN.R2.fastq.gz

这是我的代码。我遇到的问题是第二个变量 S,我不知道如何在代码中指定它,因为我的输出文件名中不需要它。

workdir: "/path/to/workdir/"

DIR=["BOB","JOHN"]
S=["S1","S2"]

rule all:
    input: 
        expand("NAME_{dir}/reads/NAME_{dir}.R1.fastq.gz", dir=DIR),
        expand("NAME_{dir}/reads/NAME_{dir}.R2.fastq.gz", dir=DIR)
        
rule rename:
    input:
        fastq1=("fastq/NAME-{dir}_{s}_L001_R1_001.fastq.gz", zip, dir=DIR, s=S),
        fastq2=("fastq/NAME-{dir}_{s}_L001_R2_001.fastq.gz", zip, dir=DIR, s=S)
    output:
        fastq1="NAME_{dir}/reads/NAME_{dir}.R1.fastq.gz",
        fastq2="NAME_{dir}/reads/NAME_{dir}.R2.fastq.gz"
        
    shell:
        """
        mv {input.fastq1} {output.fastq1}
        mv {input.fastq2} {output.fastq2}
        """

您的代码中存在几个问题。首先,输出中的 {dir} 和输入中的 {dir} 是两个不同的变量。其实输出中的{dir}是一个通配符,而输入中的{dir}expand函数的参数(而且你连这个函数都忘了调用,就是第二个问题)。

第三个问题是shell部分应该只包含一个命令。您可以尝试 mv {input.fastq1} {output.fastq1}; mv {input.fastq2} {output.fastq2},但这不是惯用的解决方案。更好的方法是创建一个生成单个文件的规则,让 Snakemake 完成其余的工作。

最后 S 值完全依赖于 DIR 值,因此它成为 {dir} 的函数,可以用输入的 lambda 求解:

workdir: "/path/to/workdir/"

DIR=["BOB","JOHN"]
dir2s = {"BOB": "S1", "JOHN": "S2"}

rule all:
    input: 
        expand("NAME_{dir}/reads/NAME_{dir}.{r}.fastq.gz", dir=DIR, r=["R1", "R2"])
        
rule rename:
    input:
        lambda wildcards:
            "fastq/NAME-{{dir}}_{s}_L001_{{r}}_001.fastq.gz".format(s=dir2s[wildcards.dir])
    output:
        "NAME_{dir}/reads/NAME_{dir}.{r}.fastq.gz",
        
    shell:
        """
        mv {input} {output}
        """