Snakemake: как использовать одно целое число из списка при каждом вызове в качестве входных данных для скрипта?

Я пытаюсь попрактиковаться в написании рабочих процессов в snakemake.

Содержимое моего Snakefile:

configfile: "config.yaml"

rule get_col:
  input:
   expand("data/{file}.csv",file=config["datname"])
  output:
   expand("output/{file}_col{param}.csv",file=config["datname"],param=config["cols"])
  params:
   col=config["cols"]
  script:
   "scripts/getCols.R"

Содержимое config.yaml:

cols:
  [2,4]
datname:
  "GSE3790_expression_data"

Мой сценарий R:

getCols=function(input,output,col) {
  dat=read.csv(input)
  dat=dat[,col]
  write.csv(dat,output,row.names=F)
}

getCols(snakemake@input[[1]],snakemake@output[[1]],snakemake@params[['col']])

Похоже, вызываются сразу обе колонки. То, что я пытаюсь сделать, - это вызов одного столбца из списка для каждого выходного файла.

Поскольку второй вывод никогда не может быть создан (оба столбца используются для создания первого вывода), snakemake выдает ошибку:

Waiting at most 5 seconds for missing files.
MissingOutputException in line 3 of /Users/rebecca/Desktop/snakemake-tutorial/practice/Snakefile:
Job completed successfully, but some output files are missing.

Немного не связанное с этим примечание, я подумал, что могу записать ввод как: 'data / {file} .csv' Но это возвращает:

WildcardError in line 4 of /Users/rebecca/Desktop/snakemake-tutorial/practice/Snakefile:
Wildcards in input files cannot be determined from output files:
'file'

Любая помощь приветствуется!


person Rebecca Eliscu    schedule 28.10.2020    source источник


Ответы (1)


Похоже, вы хотите запускать свой Rscript дважды для каждого файла, один раз для каждого значения col. В этом случае правило также нужно вызывать дважды. На мой взгляд, использование expand здесь тоже многовато. expand заполняет ваши подстановочные знаки всеми возможными значениями и возвращает список результирующих файлов. Таким образом, результатом этого правила будут все возможные комбинации между files и cols, которые простой сценарий не может создать за один прогон. Это также причина того, почему file не может быть выведен из вывода - он там раскрывается.

Вместо этого попробуйте написать свое правило проще для одного файла и столбца и развернуть полученный результат в правиле, которому этот вывод нужен как ввод. Если вы сгенерировали окончательный результат своего рабочего процесса, поместите его в качестве входных данных в rule all, чтобы сообщить рабочему процессу, какова конечная цель.

rule all:
  input:
    expand("output/{file}_col{param}.csv",
    file=config["datname"], param=config["cols"])

rule get_col:
  input:
    "data/{file}.csv"
  output:
    "output/{file}_col{param}.csv"
  params:
    col=lambda wc: wc.param
  script:
    "scripts/getCols.R"

Snakemake сделает вывод из rule all (или любого другого правила для дальнейшего использования вывода), что нужно сделать, и соответственно вызовет rule get_col.

person jafors    schedule 28.10.2020
comment
Спасибо за помощь! Не могли бы вы подробнее рассказать об использовании лямбда-слова wc (подстановочный знак)? Мне не ясно, когда переменная должна быть определена как объект с подстановочными знаками, а не просто ссылаться на нее напрямую (например, col = {param} vs. col = labda wc: wc.param). - person Rebecca Eliscu; 28.10.2020
comment
Одно замечание: мне нужно было написать col = lambda wc: wc.param как col = lambda wc: int (wc.param), чтобы код запускался в R. - person Rebecca Eliscu; 29.10.2020
comment
В моей версии лямбда-функция действительно не нужна. По сути, используйте его, если хотите каким-либо образом модулировать подстановочный знак, как вы это делали с int (). - person jafors; 29.10.2020