10

我想使用生成文件来更新由 R 代码生成的图形文件。R 代码位于目录中的各种文件中,../R并且都以.R. 图形文件在目录中../figs,都以.pdfor结尾.png。如果 R 文件的日期晚于任何图形文件,我想使用命令处理 R 文件

R --no-save < file.R

我查看了各种示例生成文件,但找不到任何我可以适应的东西。

我目前的努力(不工作)如下:

PLOTDIR= ../figs
RDIR= ../R
RFILES= $(RDIR)/*.R
PLOTS= *.pdf *.png
FIGURES= $(PLOTDIR)/$(PLOTS)
$(FIGURES): $(RFILES)
    R --no-save < $<
4

2 回答 2

2

您可以尝试以下方法。

诀窍是您需要从输入(.R 文件)中推断出输出

# Makefile
# Beware of indentation when copying use TABS

PLOTDIR = ../figs
RDIR = ../R

# list R files
RFILES = $(wildcard $(RDIR)/*.R)

# compute output file names
PDF_FIGS = $(RFILES:.R=.pdf)
PNG_FIGS = $(RFILES:.R=.png)

# relocate files in output folder
OUT_FILES = $(subst $(RDIR), $(PLOTDIR), $(PDF_FIGS) $(PNG_FIGS))

# first target is the default: simply do 'make'
all: $(OUT_FILES)

clean:
    rm $(OUT_FILES)

.PHONY: all clean

# need to split PNG from PDF rules
$(PLOTDIR)/%.png: $(RDIR)/%.R
    R --no-save < $<

$(PLOTDIR)/%.pdf $(PLOTDIR)/%.png: $(RDIR)/%.R
    R --no-save < $<

编辑以反映我的评论:每个 R 脚本使用 1 个依赖项输出文件

PLOTDIR= ../figs
RDIR= ../R

# list R files
RFILES := $(wildcard $(RDIR)/*.R)

# relocate files in output folder
OUT_FILES=$(subst $(RDIR), $(PLOTDIR), $(RFILES:.R=.out))
#$(warning $(OUT_FILES))

# first target is the default: simply do 'make'
all: $(OUT_FILES)

clean:
    rm $(OUT_FILES)

.PHONY: all clean

$(PLOTDIR)/%.out: $(RDIR)/%.R
    R --no-save < $< && touch $@
于 2012-10-19T08:46:05.927 回答
1

一个有趣的问题。这在逻辑上很简单,但与 Make 喜欢做的事情背道而驰。

这似乎有效。它依赖于模式规则的一个模糊特性:如果模式规则有多个目标,Make 推断它只需要运行一次即可更新其所有目标。

PLOTDIR = ../figs
RDIR = ../R
RFILES = $(wildcard $(RDIR)/*.R)
FIGURES = $(wildcard $(PLOTDIR)/*.pdf $(PLOTDIR)/*.png)

all: $(FIGURES)

$(PLOTDIR)/%.pdf $(PLOTDIR)/%.png: $(RFILES)
        @for x in $?; do R --no-save \< $$x; done
于 2012-10-19T08:53:50.373 回答