为了账号安全,请及时绑定邮箱和手机立即绑定

在 Snakemake 中组合多个通配符

在 Snakemake 中组合多个通配符

翻翻过去那场雪 2023-08-08 15:19:36
├── DIR1│   ├── smp1.fastq.gz│   ├── smp1_fastqc/│   ├── smp2.fastq.gz│   └── smp2_fastqc/└── DIR2    ├── smp3.fastq.gz    ├── smp3_fastqc/    ├── smp4.fastq.gz    └── smp4_fastqc/我想按样本计算读取次数,然后按目录连接所有计数。我创建一个字典,将样本 1 和 2 链接到目录 1,将样本 3 和 4 链接到目录 2DIRS,SAMPLES = glob_wildcards(INDIR+'/{dir}/{smp}.fastq.gz')# Create samples missingdef filter_combinator(combinator, authlist):    def filtered_combinator(*args, **kwargs):        for wc_comb in combinator(*args, **kwargs):            if frozenset(wc_comb) in authlist:                yield wc_comb    return filtered_combinator# Authentificationcombine_dir_samples = []for dir in DIRS:    samples, = glob_wildcards(INDIR+'/'+dir+'/{smp}.fastq.gz')    for smp in samples:        combine_dir_samples.append( { "dir" : dir, "smp" : smp} )       combine_dir_samples = { frozenset( x.items() ) for x in combine_dir_samples }dir_samples = filter_combinator(product, combine_dir_samples)然后,我创建一个规则来按样本计算我的读取次数rule all:    input:        expand(INDIR+'/{dir}/{smp}_Nreads.txt', dir_samples, dir=DIRS, smp=SAMPLES)rule countReads:    input:        INDIR+'/{dir}/{smp}_fastqc/fastqc_data.txt'    output:        INDIR+'/{dir}/{smp}_Nreads.txt'    shell:        "grep 'Total\ Sequences' {input} | awk '{{print {wildcards.dir},$3}}' > {output}"---------------------------------------------------------------# result ok├── DIR1│   ├── smp1_Nreads.txt│   └── smp2_Nreads.txt└── DIR2    ├── smp3_Nreads.txt    └── smp4_Nreads.txt> cat smp1_Nreads.txtDIR1 15082186我尝试为我的连接规则使用不同的输入语法expand(OUTFastq+'/{dir}/FastQC/{{smp}}_Nreads.txt', dir_samples, dir=DIRS)lambda wildcards: expand(OUTFastq+'/{dir}/FastQC/{wildcards.smp}_Nreads.txt', dir_samples, dir=DIRS, smp=SAMPLES)expand(OUTFastq+'/{dir}/FastQC/{wildcards.smp}_Nreads.txt', dir_samples, dir=DIRS, smp=SAMPLES)我没有找到任何解决方案,就像它不关心我的字典中的这条规则一样。
查看完整描述

1 回答

?
慕村225694

TA贡献1880条经验 获得超4个赞

首先,我认为你的解决方案过于复杂,使得它对于 Snakemake 来说不太惯用。因此,您在执行该规则时遇到了问题。无论如何,让我按照您提出的问题来回答这个问题。


两个文件相同也就不足为奇了Nreads_DIRx.txt,因为输入不依赖于输出中的任何通配符:


rule concatNreads:

    input:

        expand(INDIR+'/{dir}/{smp}_Nreads.txt', dir_samples, dir=DIRS, smp=SAMPLES)

这里,该expand函数解析dir和smp变量,生成完全指定的文件名列表。您需要的是真正取决于输出中的通配符的东西:


rule concatNreads:

    input:

        lambda wildcards: ...

是{dir}使用输出中的通配符完全指定的,因此您不需要从变量中为其分配值DIRS:


rule concatNreads:

    input:

        lambda wildcards: expand(INDIR+'/{dir}/{smp}_Nreads.txt', dir=wildcards.dir, smp=func(wildcards.dir))

现在的问题是如何实现这个func为目录生成样本列表的函数。我花了一段时间才理解您使用combine_dir_samplesand的技巧filter_combinator,所以我将其留给您func使用该代码实现该函数。但你真正需要的是 DIR -> SAMPLES 中的地图:


dir_to_samples = {"DIR1": ["smp1", "smp2"], "DIR2": ["smp3", "smp4"]}


def func(dir):

    return dir_to_samples[dir]

这dir_to_samples可能可以更容易地评估,但这是您修改后的解决方案:


for dir in DIRS:

    samples, = glob_wildcards(INDIR+'/'+dir+'/{smp}.fastq.gz')

    dir_to_samples.append({dir: samples})


查看完整回答
反对 回复 2023-08-08
  • 1 回答
  • 0 关注
  • 64 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信