我有以下规则,其中我试图将通配符sensor
约束为除以fitbit
开头的那些字符串以外的任何字符串。我面临的问题是我正在使用的正则表达式似乎匹配任何字符串,就好像该规则不存在(将不会生成任何输出文件)。
rule readable_datetime:
input:
sensor_input = rules.download_dataset.output
params:
timezones = None,
fixed_timezone = config["READABLE_DATETIME"]["FIXED_TIMEZONE"]
wildcard_constraints:
sensor = "^(?!fitbit).*" # ignoring fitbit sensors
output:
"data/raw/{pid}/{sensor}_with_datetime.csv"
script:
"../src/data/readable_datetime.R"
我收到一条带有规则(light_metrics
)的错误消息,该规则需要以readable_time
作为输入的sensor=light
的输出
MissingInputException in line 112 of features.snakefile:
Missing input files for rule light_metrics:
data/raw/p01/light_with_datetime.csv
答案 0 :(得分:2)
如果可以的话,我宁愿远离正则表达式,也许这对您有用。
假设传感器的列表如下:
sensor = ['fitbit', 'spam', 'eggs']
在规则readable_datetime
中使用
wildcard_constraints:
sensor = '|'.join([re.escape(x) for x in sensor if x != 'fitbit'])
解释:re.escape(x)
对x中的元字符进行转义,因此,如果x包含',我们将不会出现虚假匹配。要么 '*'。 x in sensor if x != 'fitbit'
应该是不言自明的,您可以根据需要使其变得复杂。最后,'|'.join()
将所有内容缝合在一起的正则表达式中只能与列表理解所捕获的传感器中的项匹配。
(为什么您的正则表达式不起作用,但我没有调查...)
答案 1 :(得分:0)
我的解决方案只是从通配符正则表达式中删除^
。之所以可行,是因为正则表达式被应用于包含通配符的整个路径,而不只是应用于通配符本身。
这里简要讨论:
https://bitbucket.org/snakemake/snakemake/issues/904/problems-with-wildcard-constraints
我的理解是,您为每个通配符指定的正则表达式将替换为整个输出路径的较大正则表达式。
搜索类似data/raw/(.*)/(.*)_with_datetime.csv
的东西,将第一个捕获组和第二个捕获组分别设为pid
和sensor
。
搜索data/raw/(.*)/((?!fitbit).*)_with_datetime.csv
,再次将第一和第二捕获组分别设为pid
和sensor
。
这是一个较小的工作示例:
rule all:
input:
"data/raw/p01/light_with_datetime.csv",
"data/raw/p01/fitbit_light_with_datetime.csv",
"data/raw/p01/light_fitbit_with_datetime.csv",
"data/raw/p01/light_fitbit_foo_with_datetime.csv",
rule A:
output:
"data/raw/{pid}/{sensor}_with_datetime.csv"
wildcard_constraints:
sensor="(?!fitbit).*"
shell:
"touch {output}"
当您运行snakemake时,它只会抱怨带有以fitbit
开头的传感器的文件丢失,但是很高兴找到其他文件。
snakemake
Building DAG of jobs...
MissingInputException in line 1 of Snakefile:
Missing input files for rule all:
data/raw/p01/fitbit_light_with_datetime.csv