访问 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 中有关在规则属性中使用函数的更多信息。
在我的 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 中有关在规则属性中使用函数的更多信息。