开发者

How to get Sweave to put graphics in separate folder AND name them after the Rnw file

开发者 https://www.devze.com 2023-04-01 03:23 出处:网络
I\'ve seen a few questions about this, but can\'t work out how to do what I want. By default, Sweave creates graphics by concatenating the name of the Rnw file and the name of the graphic object labe

I've seen a few questions about this, but can't work out how to do what I want.

By default, Sweave creates graphics by concatenating the name of the Rnw file and the name of the graphic object label.

From this question (Make Sweave + RweaveHTML put all graphics in a specified folder) If I want all my graphics in the fol开发者_StackOverflowder foo and to be named bar-graphic I can use

\SweaveOpts{prefix.string=foo/bar}

But how can I get the graphics in folder foo but named rnwfile-graphic ?


OK, this probably should be assigned to the innermost circle of hell, but the only way I know of to get the name of the currently running script is to use (abuse?) the source reference attached to functions. Consider this Sweave chunk in a file foo.Rnw

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

When I process foo.Rnw with Sweave I get:

\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}

You could make a dummy function at the top of your Sweave file, pull out the $filename from the source reference, and process it to remove the extension, e.g.:

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

and then build up the string needed for prefix.string, with say

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

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

where prefix.string contains the built up path and prefix.

Here is a complete example:

<<>>=
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)
@

that when processed by Sweave gives:

\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}

Tweak that as you see fit.


While Gavin's hack is great, if you really want Sweave to do different sorts of things, the best way to do so is to write your own driver; I use this method, for instance, for getting Sweave to scale different figures differently. You don't have to start from scratch but can just modify the existing code as needed.

There's only a couple minor functions that need to be changed for this case, however, with the namespace issues it's easier to just start with all the Sweave code; you can get the 2.13 Sweave code here.

The necessary changes are below. They add a new option, subdir, and prepend it to the original chunkprefix, which is the name of the rnw file. The SweaveParseOptions line is needed because this function is not exported by utils and is in a different source file.

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)

With the changes saved as SweaveDriversNew.R, put the option in your Rnw file like this

\SweaveOpts{subdir=foo}

And then Sweave using the new driver like this.

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

The result is that images are named foo/test-graphic.pdf, where foo is defined in the Sweave file and test is automagically taken from the name of Sweave file.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号