#snakemake
Вопрос:
У меня есть файл snakemake, в котором одно правило создает файл, из которого я хотел бы извлечь заголовок и использовать его в качестве подстановочных знаков во всех моих правилах. В руководстве по змеиному змею приведен пример, в котором он создает новые папки с именами, подобными подстановочным знакам, но если я смогу этого избежать, было бы неплохо, так как в некоторых случаях тогда потребуется создать 100-200 папок. Есть какие-нибудь предложения о том, как заставить его работать?
ссылка на руководство по змееподобию: https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html
import pandas as pd
rule all:
input:
final_report = expand('report_{fruit}.txt', fruit= ???)
rule create_file:
input:
output:
fruit = 'fruit_file.csv'
run:
....
rule next:
input:
fruit = 'fruit_file.csv'
output:
report = 'report_{phenotype}.txt'
run:
fruit_file = pd.read_csv({input.fruit}, header = 0, sep = 't')
fruits= fruit_file.columns.tolist()[2:]
for i in fruits:
cmd = 'touch report_' i '.txt'
shell(cmd)
Это упрощенный рабочий процесс, так как я на самом деле использую какой-то длинный скрипт для создания файла pheno_file.csv и файлов отчетов.
Файл pheno_file.csv разделен вкладками и может выглядеть следующим образом:
FID IID Apple Banana Plum
Mouse Mickey 0 0 1
Mouse Minnie 1 0 1
Duck Donnald 0 1 0
Комментарии:
1. Я не знаю ответа на ваш вопрос, но создание 100-200 папок не является проблемой. В любом случае у вас будет 100-200 файлов в одном каталоге.
Ответ №1:
Я думаю, что вы неправильно истолковываете пример контрольной точки snakemake. В вашем случае вам нужно создать только одну папку. У них есть подстановочный знак ( sample
) в имени папки, но эта часть выходного имени известна заранее.
checkpoint fruit_reports:
input:
fruit = 'fruit_file.csv'
output:
report_dir = directory('reports')
run:
fruit_file = pd.read_csv({input.fruit}, header = 0, sep = 't')
fruits= fruit_file.columns.tolist()[2:]
for i in fruits:
cmd = f'touch {output}/report_{i}.txt'
shell(cmd)
Поскольку вы не знаете всех названий (фруктов) заранее, вы не можете включить их в правило «все». Вам нужно сослаться на промежуточное правило, чтобы свести все воедино. Может быть, использовать файл окончательного отчета:
rule all:
input: 'report.txt'
Затем после контрольно-пропускного пункта:
def aggregate_fruit(wildcards):
checkpoint_output = checkpoints.fruit_reports.get(**wildcards).output[0]
return expand("reports/report_{i}.txt",
i=glob_wildcards(os.path.join(checkpoint_output, "report_{i}.txt")).i)
rule report:
input:
aggregate_input
output:
"report.txt"
shell:
"ls 1 {input} > {output}"