如何让Sweave将图形放在单独的文件夹中并在Rnw文件后命名它们

时间:2011-08-31 08:09:57

标签: r sweave

我已经看到了一些关于这个的问题,但是无法解决如何做我想做的事情。

默认情况下,Sweave通过连接Rnw文件的名称和图形对象标签的名称来创建图形。

从这个问题(Make Sweave + RweaveHTML put all graphics in a specified folder)如果我想把我的所有图形都放在文件夹foo中并命名为bar-graphic我可以使用

\SweaveOpts{prefix.string=foo/bar}

但是如何在foo文件夹中获取图形但命名为rnwfile-graphic?

2 个答案:

答案 0 :(得分:5)

好吧,这可能应该被分配到地狱的最里面的圈子,但我知道获取当前正在运行的脚本名称的唯一方法是使用(滥用?)附加到函数的源引用。在文件foo.Rnw

中考虑这个Sweave块
<<>>=
foo <- function(x) {x}
srcref <- attr(body(foo), "srcref")[[1]]
attr(srcref, "srcfile")$filename
@

当我用Sweave处理foo.Rnw时,我得到:

\begin{Schunk}
\begin{Sinput}
> foo <- function(x) {
+     x
+ }
> srcref <- attr(body(foo), "srcref")[[1]]
> attr(srcref, "srcfile")$filename
\end{Sinput}
\begin{Soutput}
[1] "foo.Rnw"
attr(,"encoding")
[1] "ASCII"
\end{Soutput}
\end{Schunk}

您可以在Sweave文件的顶部创建一个虚拟函数,从源引用中提取$filename,然后处理它以删除扩展名,例如:

> sub("\\.Rnw", "", "foo.Rnw")
[1] "foo"

然后构建prefix.string所需的字符串,比如说

<<>>=
fname <- sub("\\.Rnw", "", attr(srcref, "srcfile")$filename)
prefix.string <- paste("foo/", fname, "-graphic", sep = "")
@

\SweaveOpts{prefix.string=\Sexpr{prefix.string}}

其中prefix.string包含构建的路径和前缀。

这是一个完整的例子:

<<>>=
foo <- function(x) {x}
srcref <- attr(body(foo), "srcref")[[1]]
attr(srcref, "srcfile")$filename
@

<<>>=
fname <- sub("\\.Rnw", "", attr(srcref, "srcfile")$filename)
prefix.string <- paste("foo/", fname, "-graphic", sep = "")
@

\SweaveOpts{prefix.string=\Sexpr{prefix.string}}

<<fig=TRUE>>=
plot(1:10)
@

当由Sweave处理时给出:

\begin{Schunk}
\begin{Sinput}
> foo <- function(x) {
+     x
+ }
> srcref <- attr(body(foo), "srcref")[[1]]
> attr(srcref, "srcfile")$filename
\end{Sinput}
\begin{Soutput}
[1] "foo.Rnw"
attr(,"encoding")
[1] "ASCII"
\end{Soutput}
\end{Schunk}

\begin{Schunk}
\begin{Sinput}
> fname <- sub("\\.Rnw", "", attr(srcref, "srcfile")$filename)
> prefix.string <- paste("foo/", fname, "-graphic", sep = "")
\end{Sinput}
\end{Schunk}



\begin{Schunk}
\begin{Sinput}
> plot(1:10)
\end{Sinput}
\end{Schunk}
\includegraphics{foo/foo-graphic-003}

根据需要调整一下。

答案 1 :(得分:3)

虽然Gavin的黑客很棒,但如果你真的想让Sweave做各种各样的事情,那么最好的方法就是编写自己的驱动程序;例如,我使用这种方法让Sweave以不同的方式缩放不同的数字。您不必从头开始,只需根据需要修改现有代码。

对于这种情况,只需要更改几个次要功能,但是,对于命名空间问题,更容易从所有Sweave代码开始;你可以得到the 2.13 Sweave code here

必要的变更如下。他们添加了一个新选项subdir,并将其添加到原始chunkprefix,这是rnw文件的名称。需要SweaveParseOptions行,因为utils不会导出此函数,并且该函数位于不同的源文件中。

16a17,18
> SweaveParseOptions <- utils:::SweaveParseOptions
> 
69c71
<                     concordance = FALSE, expand = TRUE, figs.only = FALSE)
---
>                     concordance = FALSE, expand = TRUE, figs.only = FALSE, subdir=".")
520c522
<                    "grdevice")
---
>                    "grdevice", "subdir")
568c570
<     chunkprefix
---
>     file.path(options$subdir, chunkprefix)

将更改保存为SweaveDriversNew.R,将选项放在Rnw文件中

\SweaveOpts{subdir=foo}

然后使用这样的新驱动程序Sweave。

source("SweaveDriversNew.R")
Sweave("test.Rnw", driver=RweaveLatex)

结果是图像被命名为foo/test-graphic.pdf,其中foo在Sweave文件中定义,test自动从Sweave文件的名称中获取。