如何仅 select tsv 文件中一行的值?

How do I only select values from one row in tsv file?

编辑: 我应该补充一点,这个问题基本上正是我要问的:
问题是,当我尝试使其适应我的 Snakefile 时,我收到一条错误消息,指出 'function' object has no attribute 'unique' 指的是以下行:samples= list(units_table.SampleSM.unique())
在同一个线程中,Johannes 链接到他的 gatk 管道,该管道也为此目的使用 tsv 文件,但坦率地说,我不明白发生了什么,所以不幸的是它没有帮助。如果我能在下面的 Snakefile 中得到一些输入,我将不胜感激。

我需要通过填充基于 tsv 文件的变量来开始我的工作流程,如下所示:

flowcell    sample  library lane    R1  R2
FlowCellX   SAMPLE1 libZ    L001    fastq/FCX/Sample1_L001.R1.fastq.gz  fastq/FCX/Sample1_L001.R2.fastq.gz
FlowCellX   SAMPLE1 libZ    L002    fastq/FCX/Sample1_L002.R1.fastq.gz  fastq/FCX/Sample1_L002.R2.fastq.gz
FlowCellX   SAMPLE2 libZ    L001    fastq/FCX/Sample2_L001.R1.fastq.gz  fastq/FCX/Sample2_L001.R2.fastq.gz
FlowCellX   SAMPLE2 libZ    L002    fastq/FCX/Sample2_L002.R1.fastq.gz  fastq/FCX/Sample2_L002.R2.fastq.gz
FlowCellY   SAMPLE1 libX    L001    fastq/FCY/Sample1_L001.R1.fastq.gz  fastq/FCY/Sample1_L001.R2.fastq.gz

我的问题是我不知道如何使每对文件只有一行的 select 值,原因是我需要通过 select 构造一个读取组除 R1 和 R2 之外的所有列的值。

目前我唯一能做的就是将流动池、样本、库和泳道中每一行和每一列的每个条目组合起来,但我只想将其 select 一行中的条目每对输入文件。

到目前为止,这是我的代码:

import pandas as pd
from snakemake.utils import validate, min_version

samples = pd.read_table("samples.tsv", sep='\t', dtype=str).set_index(["flowcell", "sample"], drop=False)

samples.index = samples.index.set_levels([i.astype(str) for i in samples.index.levels])  # enforce str in index


def get_fastq1(wildcards):
    return samples.loc[(wildcards.flowcell, wildcards.sample), ["R1"]].dropna()
def get_fastq2(wildcards):
    return samples.loc[(wildcards.flowcell, wildcards.sample), ["R2"]].dropna()

rule all:
    input:
        expand("Outputs/BwaMem/{sample}_{lane}_{flowcell}.mapped.bam", sample=samples['sample'], lane=samples['lane'], flowcell=samples['flowcell']),

rule BwaMem:
    input:
        fasta = "/references/Homo_sapiens_assembly38.fasta",
        fastq1 = get_fastq1,
        fastq2 = get_fastq2,
    params:
        rgs = repr('@RG:\tID:{flowcell}.{lane}\tSM:{sample}\tLB:PlaceHolder\tPU:{flowcell}.{lane}.{sample}\tPL:Illumina')
    output:
        "Outputs/BwaMem/{sample}_{lane}_{flowcell}.mapped.bam",
    shell:
        "bwa mem -M -t 12 {input.fasta} \
        -R {params.rgs} \
        {input.fastq1} \
        {input.fastq2} | \
        samtools view -Sb - > {output}"

如果我在 tsv 文件中只有一行,这会起作用,但是当我添加第二行时,我就有了一个这样的 tsv 文件:

flowcell    sample  library lane    R1  R2
FlowCellX   SAMPLE1 libZ    L001    fastq/Sample1_L001.R1.fastq.gz  fastq/Sample1_L001.R2.fastq.gz
FlowCellY   SAMPLE2 libZ    L002    fastq/Sample2_L002.R1.fastq.gz  fastq/Sample2_L00.R2.fastq.gz

它给我这个错误信息:

InputFunctionException in line 18 of /home/oskar/01-workspace/00-temp/GVP/Snakefile:
KeyError: 9
Wildcards:
sample=SAMPLE1
lane=L001
flowcell=FlowCellY

它试图将 SAMPLE1 和 L001 与 FlowCellY 结合起来,但这不是我想要的,我只希望它 select FlowCellXSAMPLE1L001 fastq/FCX/Sample1_L001.R1.fastq.gzfastq/FCX/Sample1_L001.R2.fastq.gz 输入文件。生成的输出文件和读取组如下所示:
输出文件名:

SAMPLE1_FlowCellX_L001.mapped.bam 

阅读组:

@RG: ID:FlowCellX.L001 SM:SAMPLE1 LB:PlaceHolder PU:FlowCellX.L001.SAMPLE1 PL:Illumina

我错过了什么?

第二个问题是我不知道如何将 {library} 变量添加到 ..LB:PlaceHolder\t 所在的读取组。如果我尝试将此变量放在 expand("Outputs/BwaMem/{sample}_{lane}_{flowcell}.mapped.bam", sample=samples['sample'], lane=samples['lane'], flowcell=samples['flowcell']), 行中,它希望 {library} 出现在文件名中,而这不是我想要的。我想这个问题可以与上一个答案的解决方案一起解决吗?

一个问题是您在 rule all 中的 expand 函数将创建样本、泳道和流通池的所有组合,这会导致对样本 sheet 的无效查询(并且可能这不是你想要的)。如果将 expand(...) 放入变量并打印它,您将看到结果列表。下面的修复使用 zip 函数以并行方式连接样本、泳道和流通池。

关于 {library} 问题,您可以使用类似于 get_fastq 函数的 get_RG 函数来 return 来自示例 sheet 的适当值鉴于通配符。请参阅下文,可能有更好的解决方案,但希望这能让您朝着正确的方向前进...

import pandas as pd

samples = pd.read_csv("samples.tsv", sep='\t', dtype=str).set_index(["flowcell", "sample", "lane"], drop=False)

samples.index = samples.index.set_levels([i.astype(str) for i in samples.index.levels])  # enforce str in index

def get_fastq1(wildcards):
    return samples.loc[(wildcards.flowcell, wildcards.sample, wildcards.lane), ["R1"]].dropna()

def get_fastq2(wildcards):
    return samples.loc[(wildcards.flowcell, wildcards.sample, wildcards.lane), ["R2"]].dropna()

def get_RG(wc):
    library= samples.loc[(wc.flowcell, wc.sample, wc.lane), ["library"]].unique()[0]
    rgs = r'@RG:\tID:%(flowcell)s.%(lane)s\tSM:%(sample)s\tLB:%(library)s\tPU:%(flowcell)s.%(lane)s.%(sample)s\tPL:Illumina' \
        % {'flowcell': wc.flowcell, 
           'lane': wc.lane, 
           'sample': wc.sample, 
           'library': library}
    return rgs    

rule all:
    input:
        expand("Outputs/BwaMem/{sample}_{lane}_{flowcell}.mapped.bam", zip,
            sample=samples['sample'], lane=samples['lane'],
            flowcell=samples['flowcell']),

rule BwaMem:
    input:
        fasta = "Homo_sapiens_assembly38.fasta",
        fastq1 = get_fastq1,
        fastq2 = get_fastq2,
    params:
        rgs= get_RG,
    output:
        "Outputs/BwaMem/{sample}_{lane}_{flowcell}.mapped.bam",
    shell:
        r"bwa mem -M -t 12 {input.fasta} \
            -R '{params.rgs}' \
            {input.fastq1} \
            {input.fastq2} \
        | samtools view -Sb - > {output}"