diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..91114bf --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1,2 @@ +^.*\.Rproj$ +^\.Rproj\.user$ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b0d3a0b --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# History files +.Rhistory +.Rapp.history + +# Session Data files +.RData +# Help files (because they will be created automatically by roxygen) +*.Rd +# Example code in package build process +*-Ex.R +# Output files from R CMD build +/*.tar.gz +# Output files from R CMD check +/*.Rcheck/ +# RStudio files +.Rproj.user/ +# produced vignettes +vignettes/*.html +vignettes/*.pdf +# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 +.httr-oauth +# knitr and R markdown default cache directories +/*_cache/ +/cache/ +# Temporary files created by R markdown +*.utf8.md +*.knit.md +.Rproj.user +inst/doc diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..f0dd1c5 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,15 @@ +Package: lusweave +Type: Package +Title: Landuse Sweave Utilities +Version: 1.43.4 +Date: 2017-11-29 +Author: Markus Bonsch, Jan Philipp Dietrich, Florian Humpenoeder +Maintainer: Jan Philipp Dietrich +Description: Set of tools which simplify the usage of SWeave in R and allow to easily create PDF files based on R data. +Depends: R(>= 2.10.0), methods +Imports: xtable, + knitr, + utils +License: BSD_2_clause + file LICENSE +LazyData: no +RoxygenNote: 6.0.1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3cae23b --- /dev/null +++ b/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2016 +COPYRIGHT HOLDER: Potsdam Institute for Climate Impact Research (PIK) \ No newline at end of file diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..a9eb61d --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,13 @@ +# Generated by roxygen2: do not edit by hand + +export(swR) +export(swclose) +export(swfigure) +export(swlatex) +export(swopen) +export(swtable) +importFrom(methods,is) +importFrom(methods,new) +importFrom(utils,Sweave) +importFrom(utils,data) +importFrom(xtable,xtable) diff --git a/R/Sweave.sty b/R/Sweave.sty new file mode 100644 index 0000000..2a1b66d --- /dev/null +++ b/R/Sweave.sty @@ -0,0 +1,25 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{Sweave}{} +\RequirePackage{ifthen} +\newboolean{Sweave@gin} +\setboolean{Sweave@gin}{true} +\newboolean{Sweave@ae} +\setboolean{Sweave@ae}{true} +\DeclareOption{nogin}{\setboolean{Sweave@gin}{false}} +\DeclareOption{noae}{\setboolean{Sweave@ae}{false}} +\ProcessOptions +\RequirePackage{graphicx,fancyvrb} +\ifthenelse{\boolean{Sweave@gin}}{\setkeys{Gin}{width=\textwidth}}{}% +\ifthenelse{\boolean{Sweave@ae}}{% +\RequirePackage[T1]{fontenc} +\RequirePackage{ae} +}{}% +\DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl} +\DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\small,xleftmargin=0mm,xrightmargin=0mm} +\DefineVerbatimEnvironment{Scode}{Verbatim}{fontshape=sl} +\newenvironment{Schunk}{}{} +\newcommand{\Sconcordance}[1]{% +\ifx\pdfoutput\undefined% +\csname newcount\endcsname\pdfoutput\fi% +\ifcase\pdfoutput\special{#1}% +\else\immediate\pdfobj{#1}\fi} diff --git a/R/lusweavedata.R b/R/lusweavedata.R new file mode 100644 index 0000000..bd2d371 --- /dev/null +++ b/R/lusweavedata.R @@ -0,0 +1,9 @@ +#' lusweavedata +#' @description General lusweave-dataset +#' @aliases lusweavedata +#' @details Pleasde do not directly acces that data. It should be only used by library functions. +#' @author Jan Philipp Dietrich +#' @name lusweavedata +#' + +NULL \ No newline at end of file diff --git a/R/swR.R b/R/swR.R new file mode 100644 index 0000000..22f7fee --- /dev/null +++ b/R/swR.R @@ -0,0 +1,87 @@ +#' swR +#' +#' Function to write R code to a \code{"\linkS4class{swStream}"} object. +#' +#' Method designed to write the output of R commands to a swStream object, +#' taking care that it is correctly embedded. As \code{func} argument, you can +#' pass either the function itself or its name as a string. User defined +#' functions will only work with option one, two is only for back +#' compatibility. +#' +#' @usage swR(stream,func,...,option = "echo=FALSE") +#' @param stream The \code{swStream} object to be modified. +#' @param func The R command, that shall be ecexuted. Can be specified as a +#' string for back compatibility +#' @param ... Additional parameters passed to the function. +#' @param option Formatting options. +#' @return No return value. +#' @author Markus Bonsch +#' @export +#' @seealso +#' \code{"\linkS4class{swStream}"},\code{\link{swopen}},\code{\link{swclose}},\code{\link{swlatex}},\code{\link{swtable}},\code{\link{swfigure}} +#' @examples +#' \dontrun{ +#' test<-swopen(outfile="test.pdf") +#' swR(test,print,ls) +#' swR(test,print,"bla_blubb") +#' x<-c(1,2,3) +#' swR(test,print,paste(x,"bla")) +#' swclose(test) +#' # Only for back compatibility +#' swR(test,"print","bla_blubb") +#' } +#' +#' +# write R code to a sweaveStream object: +# define the function and its arguments +# <<"option">>= +# "func(...)" +# @ +swR<-function(stream,func,...,option = "echo=FALSE"){ + envir<-stream + stream<-get("stream",envir=envir,inherits=FALSE) + orig_stream <- stream + stufftowrite <- NULL + if(class(stream)=="swStream"){ + tryCatch({ + pos<-length(stream@functions) + args<-list(...) + + #save func (necessary in case, it is user defined) + if(is.function(func)){ + stream@functions[[pos+1]]<-func + } else{ #needed for back compatibility + stream@functions[[pos+1]]<-get(func,pos=1,inherits=TRUE) + } + #paste the command + stufftowrite<-paste("stream@functions[[",pos+1,"]](",sep="") + if(length(args)>0){ + #save all arguments as a list in the objects slot of the stream object. + stream@arguments[[pos+1]]<-args + #paste the arguments in the appropriate format + for(i in 1:length(args)){ + if(any(names(args)!="")){ + if(names(args)[i]!=""){ + stufftowrite<-paste(stufftowrite,names(stream@arguments[[pos+1]])[i],"=","stream@arguments[[",pos+1,"]][[",i,"]],",sep="") + }else{ + stufftowrite<-paste(stufftowrite,"stream@arguments[[",pos+1,"]][[",i,"]],",sep="") + } + }else{ + stufftowrite<-paste(stufftowrite,"stream@arguments[[",pos+1,"]][[",i,"]],",sep="") + } + } + } + #remove last comma + if(substr(stufftowrite,nchar(stufftowrite),nchar(stufftowrite))==",") stufftowrite<-substr(stufftowrite,1,nchar(stufftowrite)-1) + #add options and closing bracket + stufftowrite<-paste(stufftowrite,")",sep="") + stufftowrite<-c(paste("<<",option,">>=",sep=""),stufftowrite,"@") + }, error=function(e){warning("Error occurred in swR, stream will be set back to previous value.\n Error message: ",e$message,call. = FALSE);stream <- orig_stream}) + # Save the updated stream object + assign("stream",stream,envir = envir) + swlatex(envir,stufftowrite) + }else{ + stop("Input is not a sweaveStream!") + } +} + \ No newline at end of file diff --git a/R/swStream-class.R b/R/swStream-class.R new file mode 100644 index 0000000..40faf2e --- /dev/null +++ b/R/swStream-class.R @@ -0,0 +1,25 @@ +#' Class "swStream" ~~~ +#' +#' The swStream class provides an interface to the Sweave method and allows for +#' easy creation of pdf's from R output. +#' +#' The Sweave method is an interface between R and LaTeX. It processes .Rnw +#' files, that can contain LaTeX code as well as R code into proper .tex files, +#' replacing the R commands by their output. See +#' \code{http://www.stat.uni-muenchen.de/~leisch/Sweave/} for details.\cr An +#' additional style file is needed to compile the .tex file into a pdf. +#' +#' @name swStream-class +#' @docType class +#' @section Objects from the Class: Objects can be created by calls of the form +#' \code{new("swStream", name,folder, content, Sweave.sty, arguments, +#' functions, auxfiles, envir)}. +#' @author Markus Bonsch +#' @seealso +#' \code{\link{swopen}},\code{\link{swclose}},\code{\link{swlatex}},\code{\link{swR}},\code{\link{swtable}},\code{\link{swfigure}} +#' @keywords classes +#' @examples +#' \dontrun{ +#' showClass("swStream") +#' } +setClass("swStream",representation(name = "character",content = "vector",Sweave.sty="vector",functions="list",arguments="list",auxfiles="vector",envir="environment"),prototype = list(name = "",content = c("",""),Sweave.sty=c("",""),functions=list(),arguments=list(),auxfiles=c("",""),envir=.GlobalEnv)) diff --git a/R/swclose.R b/R/swclose.R new file mode 100644 index 0000000..e4abfa7 --- /dev/null +++ b/R/swclose.R @@ -0,0 +1,118 @@ +#' Close a swStream +#' +#' Function to create a pdf from a \code{"\linkS4class{swStream}"} object +#' +#' Creates a pdf with of the name specified in \code{stream@name}, with the +#' content specified in \code{stream@content}, using \code{stream@Sweave.sty} +#' as the style file. +#' +#' @usage swclose(stream,outfile="",latexpath="",clean_output=TRUE, +#' engine="knitr", save_stream=TRUE, knitquiet = FALSE) +#' @param stream The \code{swStream} object to be processed. +#' @param outfile Name of the pdf to be produced. Overwrites the name given in +#' swopen +#' @param latexpath Path of the LaTeX distribution (only necessary if not part +#' of the PATH variable). +#' @param clean_output If true, all auxiliary files will be deleted. If False, +#' they remain, including each plot in its own pdf. +#' @param engine Engine to use for conversion. Currently available: Sweave and +#' knitr. +#' @param save_stream If true (default) stream is saved to .rda file. +#' @param knitquiet If false (default) progressbar and messages are printed +#' otherwise suppressed. +#' @return No return value. +#' @author Markus Bonsch, David Klein +#' @export +#' @seealso +#' \code{"\linkS4class{swStream}"},\code{\link{swopen}},\code{\link{swlatex}},\code{\link{swR}},\code{\link{swtable}},\code{\link{swfigure}} +#' @examples +#' \dontrun{ +#' test<-swopen(outfile="test.pdf") +#' swlatex(test,"tttteeeesssstttt") +#' swclose(test) +#' #Change the name +#' swclose(test,outfile="test_2.pdf") +#' } +#' +#method to create a pdf from the swStream object +swclose<-function(stream,outfile="",latexpath="",clean_output=TRUE, engine="knitr", save_stream=TRUE, knitquiet = FALSE){ + + #Write "content" (extended by "\end{document}")to an Rnw file, + #sweave this file and produce the pdf from the .tex file. Then delete the sweaveStream + if(is.environment(stream)) { + envir<-stream + stream<-get("stream",envir=envir,inherits=FALSE) + } else { + envir <- new.env() + assign("stream",stream,envir=envir) + } + if(class(stream)=="swStream"){ + #update the name if necessary + if(outfile!=""){ + if(length(strsplit(outfile,split="/")[[1]])>1){ + tmp<-strsplit(outfile,split="/")[[1]] + outfile<-tmp[length(tmp)] + folder<-paste(tmp[1:(length(tmp)-1)],collapse="/") + } else{ + folder<-"" + } + outfile<-strsplit(outfile,".pdf", fixed=TRUE)[[1]] + outfile<-gsub("\\.","-_-_-",outfile) + stream@auxfiles<-gsub(strsplit(stream@name,".pdf", fixed=TRUE)[[1]],strsplit(outfile,".pdf", fixed=TRUE)[[1]],stream@auxfiles) + stream@name<-outfile + stream@folder<-folder + assign("stream",stream,envir = envir) + } + + stream@content<-c(stream@content,"\\end{document}") + + this_dir<-getwd() + if(stream@folder!="") setwd(stream@folder) + + if(save_stream) save(stream,file=paste0(stream@name,".rda"),compress = "xz") + + writeLines(stream@content,paste(strsplit(stream@name,".pdf", fixed=TRUE)[[1]],".Rnw",sep="")) + #create the style file if no external one is specified + writeLines(stream@Sweave.sty,"Sweave.sty") + #execute the Sweave routine which executes the R code in the Rnw file and produces a tex file + + + #Attach the stream to the global environment because this is where Sweave does the evaluation + globalenv = .GlobalEnv + tmp<-try(get("stream",envir=globalenv),silent=TRUE) + assign("stream",stream,envir=globalenv) + #now run Sweave or knitr + rnwfile <- paste(strsplit(stream@name,".pdf", fixed=TRUE)[[1]],".Rnw",sep="") + if(engine=="Sweave") { + Sweave(rnwfile,encoding="bytes") + } else if(engine=="knitr"){ + if (!requireNamespace("knitr", quietly = TRUE)) stop("The package knitr is not available!") + knitr::Sweave2knitr(rnwfile,output = rnwfile) + suppressWarnings(knitr::knit(rnwfile,quiet = knitquiet)) + } else { + stop("Unknown engine ",engine) + } + + #restore stream object in the global environment + if(!is(tmp,"try-error")) assign("stream",tmp,envir=globalenv) + + #check for command pdflatex and change latexpath in the case that it cannot be found + latexpaths <- c(latexpath,"/iplex/01/sys/applications/texlive/bin/x86_64-linux/","","not found") + for(latexpath in latexpaths) { + if(Sys.which(paste0(latexpath,"pdflatex"))!="") break + } + if(latexpath=="not found") stop("Executable pdflatex could not be found. Please check your latexpath setting") + #compile to pdf, needed two times for generation of table of contents + for(i in 1:2) { + error_code<-suppressWarnings(system(paste0(latexpath,"pdflatex --interaction=nonstopmode ",paste0(strsplit(stream@name,".pdf", fixed=TRUE)[[1]],".tex")),intern=TRUE)) + } + if(!is.null(attr(error_code,"status"))) warning("Execution of pdflatex reported an error (code ",attr(error_code,"status"),") please check the corresponding log file for further information.") + file.rename(paste(strsplit(stream@name,".pdf", fixed=TRUE)[[1]],".pdf",sep=""),paste(gsub("-_-_-","\\.",strsplit(stream@name,".pdf", fixed=TRUE)[[1]]),".pdf",sep="")) + file.rename(paste(strsplit(stream@name,".pdf", fixed=TRUE)[[1]],".log",sep=""),paste(gsub("-_-_-","\\.",strsplit(stream@name,".pdf", fixed=TRUE)[[1]]),".log",sep="")) + #remove unnecessary compilation files + if(clean_output==TRUE) log<-suppressWarnings(file.remove(stream@auxfiles)) + setwd(this_dir) + }else{ + stop("Input is not a sweaveStream!") + } +} \ No newline at end of file diff --git a/R/swfigure.R b/R/swfigure.R new file mode 100644 index 0000000..6f95c3f --- /dev/null +++ b/R/swfigure.R @@ -0,0 +1,69 @@ +#' swfigure +#' +#' Function to add R plots to a \code{"\linkS4class{swStream}"} object. +#' +#' Method designed to add an R plot to a swStream object, taking care that it +#' is correctly embedded. +#' +#' @param stream The \code{swStream} object to be modified. +#' @param plot_func The R command, that produces the plot. +#' @param ... The arguments of the plotting command. +#' @param tex_caption caption of the plot. +#' @param tex_label label for the plot in .tex file for referencing. +#' @param fig.placement Where to put the figure in the pdf. Typical LaTeX +#' allocation like "h","ht","b" allowed. +#' @param fig.width Width of the figure in the pdf as fraction of textwidth. +#' @param fig.orientation landscape or portrait. If wrongly specified, parts of +#' the figure will be cut (e.g. necessary for maps). +#' @param sw_option Sweave options. See +#' http://www.stat.uni-muenchen.de/~leisch/Sweave/Sweave-manual.pdf for details +#' @param sw_label label for the plot in the Sweave file. (Not very likely +#' necessary to be changed) +#' @return No return value. +#' @author Markus Bonsch +#' @export +#' @seealso +#' \code{"\linkS4class{swStream}"},\code{\link{swopen}},\code{\link{swclose}},\code{\link{swlatex}},\code{\link{swR}},\code{\link{swtable}} +#' @examples +#' \dontrun{ +#' test<-swopen(outfile="test.pdf") +#' swfigure(test,"plot",0,0,tex_caption="test figure",fig.width=0.5) +#' swclose(test) +#' } +swfigure<-function(stream,plot_func,...,tex_caption="",tex_label="",fig.placement="H",fig.width="",fig.orientation="portrait",sw_option="",sw_label="AUTO"){ + envir<-stream + stream<-get("stream",envir=envir,inherits=FALSE) + if(class(stream)=="swStream"){ + + #each plot has to have a different label. AUTO will take care of that + if(sw_label=="") stop("Each plot needs a different label to make things work. If you don't specify any label, it will be taken care of automatically") + if(sw_label=="AUTO") sw_label=length(stream@functions)+1 + + #remember the names of the plot files to delete them afterwards. + stream@auxfiles<-c(stream@auxfiles,paste(strsplit(stream@name,"\\.pdf")[[1]],"-",sw_label,".",c("eps","pdf"),sep="")) + assign("stream",stream,envir = envir) + #Add the orientation and the options + if(fig.orientation=="landscape") sw_label<-paste(sw_label,",width=11.69",sep="") + if(sw_option!="")sw_label<-paste(sw_label,",",sw_option,sep="") + + # change the figure width + if(fig.width!="") swlatex(envir,stufftowrite=paste("\\setkeys{Gin}{width=",fig.width,"\\textwidth}")) + + #build figure environment and put the plot command + startplot<-"\\begin{figure}" + if(fig.placement!="") startplot<-paste(startplot,"[",fig.placement,"]",sep="") + startplot<-c(startplot,"\\begin{center}") + swlatex(envir,startplot) + swR(envir,plot_func,...,option=paste(sw_label,",fig=TRUE,echo=FALSE",sep="")) + endplot<-"\\end{center}" + if(tex_caption!="") endplot<-c(endplot,paste("\\caption{",gsub("$","\\$",tex_caption,fixed=TRUE),"}",sep="")) + if(tex_label!="") endplot<-c(endplot,paste("\\label{",gsub("$","\\$",tex_label,fixed=TRUE),"}",sep="")) + endplot<-c(endplot,"\\end{figure}") + swlatex(envir,endplot) + + # change the figure width back to normal again + if(fig.width!="") swlatex(envir,stufftowrite=paste("\\setkeys{Gin}{width=1\\textwidth}")) + }else{ + print("ERROR! Input is not a sweaveStream!") + } +} \ No newline at end of file diff --git a/R/swlatex.R b/R/swlatex.R new file mode 100644 index 0000000..c5c82d8 --- /dev/null +++ b/R/swlatex.R @@ -0,0 +1,35 @@ +#' swlatex +#' +#' Function to write LaTeX code to a \code{"\linkS4class{swStream}"} object. +#' +#' Writes plain text to the swStream object. Be careful to escape R special +#' characters like "\". +#' +#' @usage swlatex(stream,...) +#' @param stream The \code{swStream} object to be modified. +#' @param ... The content, that is to be added. +#' @return No return value. +#' @author Markus Bonsch +#' @export +#' @seealso +#' \code{"\linkS4class{swStream}"},\code{\link{swopen}},\code{\link{swclose}},\code{\link{swR}},\code{\link{swtable}},\code{\link{swfigure}} +#' @examples +#' \dontrun{ +#' test<-swopen(outfile="test.pdf") +#' swlatex(test,"This is a test text") +#' swclose(test) +#' } +#' +#write latex code to a sweaveStream object +#(plain text is added to the content of the sweaveStream object, latex formatting has to be done on your own) +swlatex<-function(stream,...){ + envir<-stream + stream<-get("stream",envir=envir,inherits=FALSE) + if(class(stream)=="swStream"){ + stream@content<-c(stream@content,...) + #make sure, that the object stream is changed in the correct environment (saved in the sweave object) + assign("stream",stream,envir = envir) + }else{ + print("ERROR! Input is not a sweaveStream!") + } +} \ No newline at end of file diff --git a/R/swopen.R b/R/swopen.R new file mode 100644 index 0000000..1929aa2 --- /dev/null +++ b/R/swopen.R @@ -0,0 +1,100 @@ +setClass("swStream",representation(name = "character",folder="character",content = "vector",Sweave.sty="vector",functions="list",arguments="list",auxfiles="vector",envir="environment"),prototype = list(name = "",folder="",content = c("",""),Sweave.sty=c("",""),functions=list(),arguments=list(),auxfiles=c("",""),envir=.GlobalEnv)) + +#' Open an swStream +#' +#' Function to create a swStream object, that can be used to create a pdf +#' including R output +#' +#' +#' @param outfile name for the output pdf. Can be specified with or w/o the +#' .pdf extension. Can also contain a path to a differetn directory. +#' @param folder Path where the output shall be produced. +#' @param template A template which should be used for the PDF. Either a path +#' to a .tex-file or a vector containing the tex template code or a name of a +#' template which already comes with the library. Currently the following +#' templates are part of the library: "default","default_landscape" and +#' "david". +#' @param style Style information which should be used for the PDF. Either a +#' path to a .sty-file or a vector containing the tex style code or a name of a +#' style which already comes with the library. Currently the following styles +#' are part of the library: "default" +#' @param orientation [DEPRECATED] Please do not use this argument. It is just +#' left in the function for compatibility reasons. +#' @param envir The environment in which the object should be saved. A new +#' environment by default. +#' @return An environment containing a \code{"\linkS4class{swStream}"} object +#' named "stream" with a header for the Rnw file and the content of a +#' stylefile. +#' @author Markus Bonsch, Jan Philipp Dietrich +#' @export +#' @importFrom utils Sweave data +#' @importFrom methods is new +#' @seealso +#' \code{"\linkS4class{swStream}"},\code{\link{swclose}},\code{\link{swlatex}},\code{\link{swR}},\code{\link{swtable}},\code{\link{swfigure}} +#' @examples +#' \dontrun{ +#' test<-swopen() +#' str(test) +#' +#' testtwo<-swopen(outfile="test.pdf") +#' str(testtwo) +#' +#' } +# class to produce pdf's with embedded R tables, plots ... +# The 2 slots are "name", the name of the output pdf and "content", the stuff to write to the file (formatted according to the sweave syntax). + +#Version 1.01 - Markus bonsch +# 1.01: Added printnames to swtable + + +swopen<- function(outfile = "out.pdf",folder="",template="default",style="default",orientation=NULL,envir=new.env()){ + + #Check if outfile contains a path + if(length(strsplit(outfile,split="/")[[1]])>1){ + if(folder!="")stop("ERROR: outfile contains a path and 'folder' is specified. Can not handle that") + tmp<-strsplit(outfile,split="/")[[1]] + outfile<-tmp[length(tmp)] + folder<-paste(tmp[1:(length(tmp)-1)],collapse="/") + } + outfile<-strsplit(outfile,".pdf", fixed=TRUE)[[1]] + outfile<-gsub("\\.","-_-_-",outfile) + if(!is.null(orientation)) { + warning("Orientation argument is deprecated and will probably be removed soon. Please use an appropriate template instead (e.g. default_landscape)") + if(orientation=="landscape") { + if(template=="default") { + template <- "default_landscape" + } else { + warning("There is no appropriate landscape landscape version of the template \"",template,"\"!") + } + } + } + + #determine the auxiliary files that will be created during the process and which need to be deleted afterwards + files<-paste(strsplit(outfile,"\\.pdf")[[1]],".",c("aux","tex","Rnw","toc","out"),sep="") + files<-c(files,"Sweave.sty","Rplots.pdf") +lusweavedata <- NULL + data("lusweavedata", envir=environment(), package = "lusweave") + + #Open the stream object and fill the content with a header for the latex document + if(length(template)==1) { + if(substr(template,nchar(template)-3,nchar(template))==".tex") { + template <- readLines(template) + } else { + template <- lusweavedata$templates[[template]] + } + } + sStream<-new("swStream",name = outfile,folder=folder,content = template,auxfiles=files,envir=envir) + + if(length(style)==1) { + if(substr(style,nchar(style)-3,nchar(style))==".sty") { + style <- readLines(style) + } else { + style <- lusweavedata$styles[[style]] + } + } + sStream@Sweave.sty<-style + + stream<-envir + assign("stream",sStream,envir=stream) + return(stream) +} \ No newline at end of file diff --git a/R/swtable.R b/R/swtable.R new file mode 100644 index 0000000..91b8c51 --- /dev/null +++ b/R/swtable.R @@ -0,0 +1,171 @@ +#' swtable +#' +#' Function to add an R object to a \code{"\linkS4class{swStream}"} object. +#' +#' This method provides the possibility to display the content of an array-like +#' object in a table. It has to be specified, which two dimensions should be +#' shown by choosing them before the object is sent to the function. The +#' method is built on the \code{xtable} method. The table is then created with +#' the \code{print.xtable} method, that takes all kind of arguments like +#' placement etc. See that manuals for more information +#' +#' @param stream The \code{swStream} object to be modified. +#' @param x An array or something that can be converted to an array, that shall +#' be shown as a table. X should only contain 2 dimensions with more than 1 +#' element, otherwise it cannot be plotted as a matrix. +#' @param caption Description to be displayed in the pdf. +#' @param label Label for the tex file for referencing. +#' @param transpose Should the matrix be transposed before it is plotted? +#' @param digits How many digits shall be shown for each number? Either one +#' number or ncol()+1 numbers for each column seperately. +#' @param vert.lines 1 for vertical lines between the columns, 0 for no +#' vertical lines. If you want lines only somewhere, set this to 0 and use +#' align. +#' @param hor.lines 1 for horizontal lines between the rows, 0 for no +#' horizontal lines. A vector of length equal to nrow(x)+2 (for line above +#' first row also) with 1 and 0 indicates to put lines wherever a one is +#' mentioned, ohters will stay without lines. A vector of numbers between -1 +#' and "nrow(x)", inclusive, indicating the rows after which a horizontal line +#' should appear. +#' @param align Alignment of the table content. You can specify a single +#' character: "c" for centered, "l" for left, "r" for right. If you want +#' different alignments for different columns, specify a vector of length equal +#' to the table columns plus one (for the row names) with the alignment for +#' each column. If you want vertical lines only between some columns or around +#' the table, set vert.lines to 0 and add "|" to the alignment vector, where +#' you want to have vertical lines. +#' @param display How shall the content be displayed? Use "d" (for integers), +#' "f", "e", "E", "g", "G", "fg" (for reals), or "s" (for strings). +#' @param colsplit Number of columns after which the table is split into two (Integer). +#' Table will not be splitted up if set to NULL. +#' @param ... Further options passed to print.xtable. +#' @return No return value. +#' @author Markus Bonsch, Jan Philipp Dietrich +#' @importFrom xtable xtable +#' @export +#' @seealso +#' \code{"\linkS4class{swStream}"},\code{\link{swopen}},\code{\link{swclose}},\code{\link{swlatex}},\code{\link{swR}},\code{\link{swfigure}} +#' @examples +#' \dontrun{ +#' sw <- swopen(outfile="test.pdf") +#' a <- array(1:45,c(5,2,3),dimnames=list(paste0("a",1:5),paste0("b",1:2),paste0("c",1:3))) +#' print(a) +#' swtable(sw, a[,,1], "test 1") +#' swtable(sw, a[,1,], "test 2") +#' swtable(sw, a[,1,], "transpose test", transpose=TRUE) +#' swtable(sw, a[,1,], "colsplit test", transpose=TRUE, colsplit=2) +#' swclose(sw) +#' } +swtable<-function(stream,x,caption=NULL, label=NULL,transpose=FALSE, digits=NULL, vert.lines=1, hor.lines=1, align="c", display=NULL, colsplit=NULL, ...){ + + if(!is.null(caption)) caption <- gsub("$","\\$",caption,fixed=TRUE) + + if(is.data.frame(x)) x <- as.matrix(x) + + x <- as.array(x) + if(length(dim(x))>2) { + #create matrix from data which has the wrong dimensionality + idim <- (dim(x)!=1) + if(sum(idim)>2) stop("Input has more than 2 dimensions which contain more than 1 element. Unable to convert this data to a xtable matrix") + if(sum(idim)==0) idim[1:2] <- TRUE + if(sum(idim)==1) idim[which(!idim)[1]] <- TRUE + x <- array(x,dim=dim(x)[idim],dimnames=list(dimnames(x)[[which(idim)[1]]],dimnames(x)[[which(idim)[2]]])) + } + #Starting from here x is 2D + if(transpose) x <- aperm(x) + + envir<-stream + stream<-get("stream",envir=envir,inherits=FALSE) + if(class(stream)=="swStream"){ + # Take care of alignment, vertical and horizontal lines + if(length(hor.lines)==1){ + if(hor.lines==0){ + hor.lines=NULL + } else if (hor.lines==1){ + hor.lines=-1:dim(x)[1] + } else { + warning("hor.lines not specified correctly, no horizontal lines will be plotted in the table") + hor.lines<-NULL + } + } else if (is.vector(hor.lines)){ + if((length(hor.lines)==dim(x)[1]+2)&&(min(hor.lines)>=0)&&(max(hor.lines<=1))){ + tmp<-vector() + for(i in -1:(length(hor.lines)-2)){ + if(hor.lines[i+2]==1) tmp<-c(tmp,i) + } + hor.lines<-tmp + } else if((min(hor.lines)>=-1)&&(max(hor.lines)<=dim(x)[1])){ + print("yresy") + #nothing to be done + } else{ + warning("hor.lines not specified correctly, no horizontal lines will be plotted in the table") + hor.lines<-NULL + } + } else{ + warning("hor.lines not specified correctly, no horizontal lines will be plotted in the table") + hor.lines<-NULL + } + + if(length(align)==1){ + if(vert.lines==0){ + align<-rep(align,dim(x)[2]+1) + } else if (vert.lines==1){ + align<-c(rep(paste("|",align,sep=""),dim(x)[2]),paste("|",align,"|",sep="")) + } + } else if(length(align)==dim(x)[2]+1){ + if(vert.lines==1){ + if(length(grep("\\|",align))==0){ + align<-c(paste("|",align[1:length(align)-1],sep=""),paste("|",align[length(align)],"|",sep="")) + } else{ + tmp<-vector() + for(i in 1:length(align)){ + if(length(grep("\\|",align[1]))==0){ + tmp<-c(tmp,paste("|",align[i],sep="")) + } else{ + tmp<-c(tmp,align[i]) + } + } + #align <- tmp + } + } else{ + #nothing to be done + } + } else{ + warning("Alignment is wrongly specified. Standard alignment will be used") + align<-c(rep("|c",dim(x)[2]),"|c|") + } + out <- list() + i <- 1 + if(!is.null(colsplit)) { + parts <- dim(x)[2] %/% colsplit + 1 + while(dim(x)[2]>colsplit) { + out[[i]] <-xtable(x[,1:colsplit, drop=FALSE],caption=paste0(caption," [PART ", i, "/",parts,"]"),label=label,align=align[1:(colsplit+1)],digits=digits,display=display) + x <- x[,-(1:colsplit), drop=FALSE] + align <- align[-(2:(colsplit+1))] + align[1] <- sub("^\\|","",align[1]) + i <- i + 1 + } + } + if(i>1) { + caption <- paste0(caption," [PART ", i, "/",parts,"]") + } + out[[i]] <- xtable(x,caption=caption,label=label,align=align,digits=digits,display=display) + for(o in out) { + if("hline.after" %in% names(list(...))){ + if(Sys.info()[['sysname']]=="Linux"){ + swlatex(envir,print(o,file='/dev/null/',...)) + } else{ + swlatex(envir,print(o,file='NUL',...)) + } + } else { + if(Sys.info()[['sysname']]=="Linux"){ + swlatex(envir,print(o,hline.after=hor.lines,file='/dev/null',...)) + } else{ + swlatex(envir,print(o,hline.after=hor.lines,file='NUL',...)) + } + } + } + }else{ + stop("Input is not a sweaveStream!") + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..a18f86d --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# R lusweave package + +## Purpose and Functionality + +Set of tools which simplify the usage of SWeave/Knitr in R and allow to easily create PDF files based on R data. + + +## Installation + +For installation of the most recent package version an additional repository can be added in R: + +```r +options(repos = c(CRAN = "@CRAN@", rd3mod_repo = "http://www.pik-potsdam.de/rd3mod/R/")) +``` +The additional repository can be made availably permanently by adding the line above to a file called `.Rprofile` stored in the home folder of your system (`Sys.glob("~")` in R returns the home directory). + +After that the most recent version of the package can be installed using `install.packages`: + +```r +install.packages("lusweave") +``` + +Package updates can be installed using `update.packages` (make sure that the additional repository has been added before running that command): + +```r +update.packages() +``` + +## Questions / Problems + +In case of questions / problems please contact Jan Dietrich . diff --git a/data/lusweavedata.rda b/data/lusweavedata.rda new file mode 100644 index 0000000..2115268 Binary files /dev/null and b/data/lusweavedata.rda differ diff --git a/lusweave.Rproj b/lusweave.Rproj new file mode 100644 index 0000000..5a4617f --- /dev/null +++ b/lusweave.Rproj @@ -0,0 +1,17 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +BuildType: Package +PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace diff --git a/man/.gitignore b/man/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/man/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore