Snakemake expand(): using a helper function (zip) and imputing wildcards?
1
0
Entering edit mode
26 days ago
adixon3 • 0

I am wondering if it is possible to combine both helper functions and wildcards using snakemake's expand().

This is not what I want, but it works:

report = lambda wildcards: expand("{sample_directory}/{sample}.A.report.html", zip, sample_directory=config["sample_directory"], sample=config["sample"])

This works with the helper function zip() to tie the {sample_directory} and {sample} together into something like this:

sample_1/sample_1.A.report.html

Here's the issue: I want to keep {sample_directory} and {sample} zipped together for this output, but the letter A (hardcoded above) should actually be a wildcard itself like so:

report = lambda wildcards: expand("{sample_directory}/{sample}.{ABCDE}.report.html", zip, sample_directory=config["sample_directory"], sample=config["sample"])

Where an example of outputs would be:

  • sample_1/sample_1.A.report.html
  • sample_1/sample_1.B.report.html
  • sample_1/sample_1.C.report.html ...

Can expand() do something like this where there are some wildcards with a function applied and others without in the same expand()? I have tried masking the {ABCDE} wildcard like so {{ABCDE}}, but it doesn't work...

snakemake • 353 views
ADD COMMENT
0
Entering edit mode

lambda wildcards are for lookups, like when you have a dictionary and need to use a function to get the value. Where is your lookup function?

ADD REPLY
0
Entering edit mode

I agree with Jeremy that your question lacks context. You should provide at least the full rule in which the statement is to appear, including input and output. Otherwise, if you have single scalar values, you can just use python string concatenation with '+'. Also, in the beginning, one tends to overcomplicate things. More often than not there is an easier way than using lambda functions and simple problems should be rather addressed with rule logic.

ADD REPLY
0
Entering edit mode

Not totally sure I'm right about your use case (are those config entries lists of strings, which is why you need to zip them?) but, you can nest multiple calls to expand, and if you combine that with doubled-up braces in the string and zip in one of the two calls, I think it could do what you're looking for.

$ cat test.smk 
SAMPLE_DIRS = ["sample_1", "sample_2", "sample_3"]
SAMPLES = ["sample_1", "sample_2", "sample_3"]
for path in expand(
        expand("{sample_directory}/{sample}.{{ABCDE}}.report.html", zip, sample_directory=SAMPLE_DIRS, sample=SAMPLES),
        ABCDE=["A", "B", "C", "D", "E"]):
    print(path)
$ snakemake --quiet all -s test.smk
sample_1/sample_1.A.report.html
sample_1/sample_1.B.report.html
sample_1/sample_1.C.report.html
sample_1/sample_1.D.report.html
sample_1/sample_1.E.report.html
sample_2/sample_2.A.report.html
sample_2/sample_2.B.report.html
sample_2/sample_2.C.report.html
sample_2/sample_2.D.report.html
sample_2/sample_2.E.report.html
sample_3/sample_3.A.report.html
sample_3/sample_3.B.report.html
sample_3/sample_3.C.report.html
sample_3/sample_3.D.report.html
sample_3/sample_3.E.report.html
ADD REPLY
0
Entering edit mode
26 days ago
Michael 55k

Why not just:

report = expand(config["sample_directory"]+"/"+config["sample"]+".{letter}.report.html", letter = ["A", "B", "C"])

However, I noticed that without some context, this may not be worth much. Here is a minimal ruleset that illustrates the application:

LETTERS = ["A", "B", "C"]
rule all:
     input:
        report = expand(config["sample_directory"]+"/"+config["sample"]+".{letter}.report.html", letter = LETTERS )

rule generate_reports:
     input: "{dir}/{sample}.fastq"
     output: expand("{{dir}}/{{sample}}.{letter}.report.html", letter = LETTERS)
     shell:
               """
               for F in {output} 
               do 
                    touch $F 
               done                       
              """
ADD COMMENT

Login before adding your answer.

Traffic: 1794 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6