PaulHurleyuk
PaulHurleyuk

Reputation: 8169

Is there a way to push an R script file into a sweave document (opposite of tangle)

I often create specific sweave files to do analyses and produce pdf documents, however, sometimes I want to take an existing R script file and run it while producing a pdf of the commands and output together. I know there is a tangle command that pulls the R commands out of an rnw sweave file to create an R script, but I want the opposite.

Edit: I have considered creating a sweave file that just sources my R script, but I'd need to edit the sweave file each time, and it wouldn't deal very well with plots and graphics.

so for an example R script like this (pseudo code, might not run)

head(mcars)
1+1
x<-3
describe(mcars)
p <- ggplot(mtcars, aes(wt, mpg)) 
p + geom_point() 
print(p)

It would generate

<<echo=TRUE, result=latex>>= 
print(xtable(head(mcars)))
@ 
<<echo=TRUE, include=TRUE>>=
1+1
x<-3
@ 
<<echo=TRUE, result=latex>>= 
print(xtable(describe(mcars)))
@ 
<<echo=TRUE, fig=TRUE, include=TRUE>>= 
p <- ggplot(mtcars, aes(wt, mpg)) 
p + geom_point() 
print(p)
@ 

Anyone done this ?

Upvotes: 3

Views: 1873

Answers (2)

Aaron - mostly inactive
Aaron - mostly inactive

Reputation: 37754

No, but it's not too hard to build one off of source(file, echo=TRUE). With the below functions sourced, the following function creates a LaTeX file. Try it out!

latexR("code.R")

I tried it with the following code.R file:

c("hi",
  "there")
1+1
a <- 5
plot(1:a) # a plot
# hi there
data.frame(a=1:5, b=LETTERS[1:5])

Below are the functions. The latex S3 method is how you would get it to output special LaTeX formatting for a given object type, otherwise it just outputs the output verbatim. It also sets the default graphics device to save to pdf and output the filename.

latex <- function(obj) {
  UseMethod("latex")
}
latex.data.frame <- function(obj) {
  print(xtable(obj), floating=FALSE)
}
latex.default <- function(obj) {
  cat("\\begin{Soutput}\n")
  if (isS4(obj)) 
    methods::show(obj)
  else print(obj)
  cat("\\end{Soutput}\n")
}

fig <- function(...) {
  i <<- i+1
  n <- paste(nam, formatC(i, width=3, flag="0"), sep="-")
  f <- paste(n, "pdf", sep=".")
  cat("\\includegraphics{", n, "}\n",sep="")
  pdf(file=f, ...)
}

stopfig <- function() { if(dev.cur()!=1) dev.off() }

latexR <- function(file, base=sub(".R","", file)) {
  eval.with.vis <- function(expr, envir = parent.frame(), enclos = if (is.list(envir) ||
                         is.pairlist(envir)) parent.frame() else baseenv())
    .Internal(eval.with.vis(expr, envir, enclos))  
  on.exit(sink())
  sink(paste(base,"tex",sep="."))
  cat("\\documentclass{article}\n\\usepackage{Sweave}\n\\begin{document}\n") 
  environment(fig) <- list2env(list(i=0, nam=base))
  options(device=fig)
  exprs <- parse(file)
  srcrefs <- attr(exprs,"srcref")
  lastshown <- 0
  for(i in seq_along(exprs)) {
    srcref <- srcrefs[[i]]
    dep <- getSrcLines(attr(srcref, "srcfile"), lastshown+1, srcref[3L])
    lastshown <- srcref[3L]
    cat("\\begin{Sinput}\n", paste(dep, collapse="\n"), "\n\\end{Sinput}\n", sep="")
    yy <- eval.with.vis(exprs[i])    
    stopfig()
    if(yy$visible) latex(yy$value)
  }
  cat("\\end{document}")
}

Upvotes: 2

Yihui Xie
Yihui Xie

Reputation: 30114

I have a package named knitr under development which may be suitable for you, but I need to warn you that it is still at an early stage of development, so bugs may exist. Read the section on Code Reference in the incomplete manual https://github.com/downloads/yihui/knitr/knitr-manual.pdf

Basically you write an empty chunk in Sweave like

<<my-chunk-label>>=
@

and you use the same label in an external R script (e.g. foo.R)

## @knitr my-chunk-label
1 + 1; x <- 3

The chunk option ref is used to specify the path of the script (e.g. ref=foo.R); knitr will read the R script and match labels with the Rnw document.

Upvotes: 6

Related Questions