访问 Snakemake 中函数返回的列表的特定元素

Access specific element of a list returned by a function in Snakemake

在我的 Snakemake 工作流程中,我定义了一个函数,它使用之前在工作流程中生成的文件,解析它和 returns 2 个元素的列表,例如:

def get_param_value(wildcards) :
    # do stuff with the wildcards and some files
    return ["element1","element2"]

然后我想在后续规则中使用返回列表的每个值作为独立 params,例如:

rule example :
    input :
        'input_file.txt'
    output :
        'output_file.txt'
    params :
        param1 = "element1", # First element of the list returned by get_param_value function
        param2 = "element2" # Second element of the list returned by get_param_value function
    shell :
        'somecommand -i {input} -smth1 {params.param1} -smth2 {params.param2} -o {output} ;'

我试过直接在规则中使用函数,

params :
    param1 = get_param_value[0],
    param2 = get_param_value[1]

但我得到一个 TypeError : 'function' object is not subscriptable(这是预期的,因为它是一个函数)。

你有解决办法吗?

你可以做到:

def get_param_value(wildcards,index) :
    with open('file_from_workflow_using_wildcards') as file :
        # do stuff
        res = ["element1","element2"] 
        return res[index]

rule example :
    input :
        'input_file.txt'
    output :
        'output_file.txt'
    params :
        param1 = get_param_value(wildcards,0), # First 
        param2 = get_param_value(wildcards,1) # Second 
    shell :
        'somecommand -i {input} -smth1 {params.param1} -smth2 {params.param2} -o {output} ;'

或更好地使用代码中的函数:

res = get_param_value(wildcards)

params :
    param1 = res[0],
    param2 = res[1]

经过一些修改并感谢 Mario Abbruscato 的建议,这成功了:我在规则的 params 指令中使用了 lambda 函数来提取列表的元素和将它们分配给不同的参数:

rule example :
    input :
        'input_file.txt'
    output :
        'output_file.txt'
    params :
        params = lambda wildcards : get_param_value(wildcards)
    shell :
        'somecommand -i {input} -smth1 {params.param1[0]} -smth2 {params.param2[1]} -o {output} ;'

你很接近。您可以避免使用 lambda 并使用一个函数,只需将其名称放在不带圆括号或方括号的位置,例如 params: funcname。然后 Snakemake 会自动调用具有该名称的函数,并且通配符也会被传递。

这可以在您的上下文中应用如下:

def get_param_value(wildcards) :
    return ["elem1","elem2"]

rule example :
    output :
        'output_file.txt'
    params : 
        string_list = get_param_value
    shell :
        'echo  -param1 {params.string_list[0]} -param2: {params.string_list[1]}'

您可以自己运行,这是一个最小的(有效的)示例,在执行时会产生以下结果:

$ snakemake -np -c1

rule example:
    output: output_file.txt
    jobid: 0
    resources: tmpdir=/var/folders/5_/6_lmbd65717dly07dk7r7q200000gn/T

echo "param1: elem1" "param2: elem2"

阅读 documentation 中有关在规则属性中使用函数的更多信息。