调用Rscript

时间:2017-02-14 06:11:07

标签: r makefile rscript r-package

我正在编写一个生成Makefile的R包,我需要在制作目标之前编写一个Makefile来调用Rscript。该问题的MWE如下。因为.INIT的右侧不执行而导致退出错误。为file.rds编写食谱不符合我的需要。

a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`

all: file2.rds

file2.rds: file.rds
        cp file.rds file2.rds

clean:
        rm file.rds file2.rds

我该怎么做才能解决这个Makefile并保持便携性?从R扩展手册中,我无法使用$(shell来完成我想要完成的任务。

编辑

从@ Spacedman的第一个回答中,我了解到.INIT是“扩展”/执行的,当且仅当它被用作某个地方的变量时。太棒了! @Spacedman,我邀请您将以下Makefile复制到您自己的答案中,以便我给您信任。

a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`

all: file2.rds

file2.rds:
        echo "file.rds should not have been built."

file3.rds:
        echo -n $(.INIT)
        cp file.rds file3.rds

clean:
        rm file.rds file2.rds

以下是我所希望的结果。

$ make file2.rds
echo "file.rds should not have been built."
file.rds should not have been built.
$ ls file.rds
ls: cannot access file.rds: No such file or directory
$ make file3.rds
echo -n `Rscript -e 'saveRDS('1', "file.rds")'`
cp file.rds file3.rds
$ ls file.rds
file.rds

1 个答案:

答案 0 :(得分:1)

我认为您需要使用:=$(shell ...)

.INIT := $(shell Rscript -e 'saveRDS('$(a)', "file.rds")')

这会产生simply expanded variable而不是recursively expanded variable。我认为,即使查看.INIT的定义,Make也不会烦恼,因为它从未使用过。

反引号在Make中不会像这样工作,你必须使用$(shell ...)。你真的不能在任何地方使用$(shell ...) 吗?

https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_6.html

测试:

$ rm file.rds  file2.rds 
$ make
cp file.rds file2.rds
$ ls file*rds
file2.rds  file.rds

似乎显示make通过R脚本创建了file.rds

如果您可以将反引号字符串放入配方中,您可以使其正常工作(如您所发现的那样!)。注意我不认为你需要回显字符串,你可以扩展它,这似乎有效:

a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`

all: file2.rds

file2.rds:
    echo "file.rds should not have been built."

file3.rds:
    $(.INIT)
    cp file.rds file3.rds