Is there a way to generate tables in tex format in R and then call them in my *.rnw file
I have to geenerate a lot of tables using some userdefined function and then use them in my latex file through sweave/knitr.
Here is a simplified example to illustrate my point...
Data:
x1 <- round(rnorm(10),2)
x2 <- sample(c('a','b','c'),10,replace=TRUE)
data1 <- cbind(x1,noquote(x2));data1 <- as.data.frame(data1)
names(data1)=c('X1','X2')
Now I want to put this data1 in a tex file as follows
latex(data1,file='myfile.tex')
When running the above in my sweave document R-studio was getting stuck in the sense that the process would not end.
I get the following error
No file file1170690e2c79.aux.
*geometry* driver: auto-detecting
*geometry* detected driver: dvips
[1] (C:\Users\~~~\AppData\Local\Temp\RtmpeuvW08\file1170690e2c79.aux) )
Output written on file1170690e2c79.dvi (1 page, 604 bytes).
Transcript written on file1170690e2c79.log.
So, I used the following
sink('myfile.tex')
latex(data1,file='')
sink()
I guess there might be a better way. I do not not what mistake I am doing in the latex command.
I would appreciate if someone can help me with this by providing me a better approach
Here is my sweave file
\documentclass{article}
\usepackage{ctable}
\title{Untitled}
\begin{document}
\maketitle
<<somechunk,results=tex,echo=FALSE>>=
x1 <- round(rnorm(10),2)
x2 <- sample(c('a','b','c'),10,replace=TRUE)
data1 <- cbind(x1,noquote(x2));data1 <- as.data.frame(data1)
names(data1)=c('X1','X2')
sink('myfile.tex')
latex(data1,file='')
sink()
#
Here is my table 1 \include{myfile}
\end{document}
As suggested in the other answers, the easiest
(with Hmisc::latex or xtable)
is usually to generate the LaTeX code only when needed.
If this is not possible, the following should work:
tmp <- latex(data1,file='myfile.tex')
What happens is that latex creates the file
and returns an object of class latex.
The print method is then called, but it tries to compile the file
and display the results, which is not desired in your case.
Assigning the result to a variable (which will not be used),
or wrapping the call in invisible, suppresses the call to print.
invisible( latex(data1,file='myfile.tex') )
You could use the xtable package:
\documentclass{article}
\usepackage{ctable}
\begin{document}
<<somechunk,results=tex,echo=FALSE,results=hide>>=
library(xtable)
x1 <- round(rnorm(10),2)
x2 <- sample(c('a','b','c'),10,replace=TRUE)
data1 <- cbind(x1,noquote(x2));data1 <- as.data.frame(data1)
names(data1)=c('X1','X2')
#
Here is my table 1:
<<results=tex, echo=FALSE>>=
xtable(data1)
#
\end{document}
Related
I have several datasets each of which have a common grouping factor. I want to produce one large report with separate sections for each grouping factor. Therefore I want to re-run a set of rmarkdown code for each iteration of the grouping factor.
Using the following approach from here doesnt work for me. i.e.:
---
title: "Untitled"
author: "Author"
output: html_document
---
```{r, results='asis'}
for (i in 1:2){
cat('\n')
cat("#This is a heading for ", i, "\n")
hist(cars[,i])
cat('\n')
}
```
Because the markdown I want to run on each grouping factor does not easily fit within one code chunk. The report must be ordered by grouping factor and I want to be able to come in and out of code chunks for each iteration over grouping factor.
So I went for calling an Rmd. with render using a loop from an Rscript for each grouping factor as found here:
# run a markdown file to summarise each one.
for(each_group in the_groups){
render("/Users/path/xx.Rmd",
output_format = "pdf_document",
output_file = paste0(each_group,"_report_", Sys.Date(),".pdf"),
output_dir = "/Users/path/folder")
}
My plan was to then combine the individual reports with pdftk. However, when I get to the about the 5th iteration my Rstudio session hangs and eventually aborts with a fatal error. I have ran individually the Rmd. for the grouping factors it stops at which work fine.
I tested some looping with the following simple test files:
.R
# load packages
library(knitr)
library(markdown)
library(rmarkdown)
# use first 5 rows of mtcars as example data
mtcars <- mtcars[1:5,]
# for each type of car in the data create a report
# these reports are saved in output_dir with the name specified by output_file
for (car in rep(unique(rownames(mtcars)), 100)){
# for pdf reports
rmarkdown::render(input = "/Users/xx/Desktop/2.Rmd",
output_format = "pdf_document",
output_file = paste("test_report_", car, Sys.Date(), ".pdf", sep=''),
output_dir = "/Users/xx/Desktop")
}
.Rmd
```{r, include = FALSE}
# packages
library(knitr)
library(markdown)
library(rmarkdown)
library(tidyr)
library(dplyr)
library(ggplot2)
```
```{r}
# limit data to car name that is currently specified by the loop
cars <- mtcars[rownames(mtcars)==car,]
# create example data for each car
x <- sample(1:10, 1)
cars <- do.call("rbind", replicate(x, cars, simplify = FALSE))
# create hypotheical lat and lon for each row in cars
cars$lat <- sapply(rownames(cars), function(x) round(runif(1, 30, 46), 3))
cars$lon <- sapply(rownames(cars), function(x) round(runif(1, -115, -80),3))
cars
```
Today is `r Sys.Date()`.
```{r}
# data table of cars sold
table <- xtable(cars[,c(1:2, 12:13)])
print(table, type="latex", comment = FALSE)
```
This works fine. So I also looked at memory pressure while running my actual loop over the Rmd. which gets very high.
Is there a way to reduce memory when looping over a render call to an Rmd. file?
Is there a better way to create a report for multiple grouping factors than looping over a render call to an Rmd. file, which doesn't rely on the entire loop being inside one code chunk?
Found a solution here rmarkdown::render() in a loop - cannot allocate vector of size
knitr::knit_meta(class=NULL, clean = TRUE)
use this line before the render line and it seems to work
I am dealing with the same issue now and it's very perplexing. I tried to create some simple MWEs but they loop successfully on occasion. So far, I've tried
Checking the garbage collection between iterations of rmarkdown::render. (They don't reveal any special accumulations.)
Removing all inessential objects
Deleting any cached files manually
Here is my question:
How can we debug hangs? Should we set up special log files to understand what's going wrong?
I have some difficulties implementing a (beamer) presentation. Everything works fine until I include a function which checks a specific condition and accordingly returns the output (graph - print text). Without that function it works fine. So how can I either graph or print the output?
\documentclass[10pt]{beamer}
\usepackage[T1]{fontenc}
\begin{document}
\begin{frame}{test}
<<echo=FALSE, fig.height = 4>>=
dates <- seq(as.Date("2015-02-13"), as.Date("2015-02-22"), by = "days")
b <- c(1,1,1,1,2,2,3,3,3,0)
c <- c(20,30,26,20,30,40,5,10,4,0)
d <- c(11,2233,12,2,22,13,23,23,100,0)
df <- data.frame(dates,b,c,d)
plot(df)
test <- function(df) {
if(sum(tail(df[2:ncol(df)], 1)) > 0) { # check only last date
return(plot(df))
} else {
print("Have a nice day!")
}
}
test(df)
#
\end{frame}
\end{document}
knitr wraps output in verbatim as can be seen from the TEX that the Rnw in the question produces:
\begin{frame}{test}
\begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{kframe}
\begin{verbatim}
## [1] "Have a nice day!"
\end{verbatim}
\end{kframe}
\includegraphics[width=10cm,height=8cm]{figure/unnamed-chunk-2-1}
\end{knitrout}
\end{frame}
However:
It is straightforward to use Sweave or knitr with beamer; the only thing you need to be careful of is you have to add the fragile option to the frames that contain verbatim code. [Source]
Therefore, the frame needs the fragile option:
\begin{frame}[fragile]{test}
With fragile make sure not to indent \end{frame}. (This happened to me after copying the code from the question …)
I'm a beginner in using knitr to generate a report.
I have a R script (see below for an example; BTW I'm using RStudio for all of this) that runs without error and the output is a data frame. My rnw.file looks like this:
% !Rnw weave = knitr
\documentclass[a4paper]{article}
\begin{document}
<<echo=FALSE,message=FALSE>>=
source("test.R")
kable(test.mat)
#
\end{document}
which displays the table quite nicely. The only problem I have is with the ">" (greater than) sign in the last column which is shown as "¿".
In found something about using
\usepackage[T1]{fontenc}
but this doesn't seem to do the trick here. Having included this, I can start compiling the script but after 10 minutes or so (and before it only took me some seconds to compile) I run into an error (exit code: 1).
Thanks in advance!
R.script (saved as "test.R"):
temp <- 12
test.mat <- as.data.frame(matrix(NA,ncol=2,nrow=1))
test.mat$V1 <- 2
test.mat$V2 <- paste(temp,"subjects > 28 days",sep=" ")
> is a mathematical symbol and as so it is not recognized unless it is not embedded in a a mathematical environment (inline or as a bloc.)
Try this code.
$>$
A (not so elegant) solution
The behavior of kable remains strange. After I've analyzed the latex code that it produces I've tried this solution, which is not so elegant, but it works. Hoping that some other users will provide more efficient solutions. Here is my code.
% !Rnw weave = knitr
\documentclass[a4paper]{article}
\begin{document}
<<echo = F, message = FALSE>>=
source("test.R")
aa1
#
\end{document}
where the test.R is:
temp <- 12
test.mat <- as.data.frame(matrix(NA,ncol=2,nrow=1))
test.mat$V1 <- 2
test.mat$V2 <- paste(temp,"subjects > 28 days",sep=" ")
aa <- kable(test.mat, format = "latex")
aa1 <- gsub(">", "$>$", aa)
and here is the result:
I can't explain why it is working now, but here is what I found I should use in the preambel:
\usepackage{lmodern}
\usepackage[T1]{fontenc}
Found this in another thread (not really related to my question), but now I get what I want in the R output (no changes required in the R.script) as well as in the pdf.
I am trying to write a vignette based on some example data included with my package. I want the vignette to be as robust as possible to minor changes in example dataset -- for example an id changing.
What I was hoping to do is to define the ids in a hidden code chunk:
<<echo=FALSE, results=hide>>=
ex_id <- functionToGetID() ## Let's assume it returns 1.
#
Then use that variable to insert into functions later in the document. Something like:
<<>>=
someFunction(id = get("ex_id"))
#
The goal is for the text in the vignette to show:
someFunction(id = 1) ## and NOT someFunction(id = get("ex_id"))
I am not sure how to inject a variable into the code chunk, such that the LaTeX result only shows the value of the variable, and not how the variable was called.
Suppose I have an object x in my current session:
x <- 1
How can I use this object in an Sweave or knitr document, without having to assign it explicitly:
\documentclass{article}
\begin{document}
<<>>=
print(x)
#
\end{document}
Reason I am asking is because I want to write an R script that imports data and then produces a report for each subject using an Sweave template.
I would take a slightly different approach to this, since using global variables reduces the reproducibility of the analysis. I use brew + sweave/knitr to achieve this. Here is a simple example.
# brew template: "template.brew"
\documentclass{article}
\begin{document}
<<>>=
print(<%= x %>)
#
\end{document}
# function to write report
write_report <- function(x){
rnw_file <- sprintf('file_%s.rnw', x)
brew::brew('template.brew', rnw_file)
Sweave(rnw_file)
tex_file <- sprintf('file_%s.tex', x)
tools::texi2pdf(tex_file, clean = TRUE, quiet = TRUE)
}
# produce reports
dat <- 1:10
plyr::l_ply(dat, function(x) write_report(x))
I think it just works. If your Sweave file is named "temp.Rnw", just run
> x <- 5
> Sweave("temp.Rnw")
You'll have to worry about naming the resulting output properly so each report doesn't get overwritten.
Both Sweave and knitr makes use of the global environment (see globalenv()) when evaluating R code chunks, so whatever in your global environment can be used for your document. (Strictly speaking, knitr uses the parent frame parent.frame() which is globalenv() in most cases)
Another option I have used in the past is to have the Sweave code open a file,
in my R session
write.csv(x, "tabletoberead.csv")
in my sweave document
<<label=label, echo=FALSE>>=
datatobeused<-read.csv("tabletoberead.csv")
...more manipulations on data ....
#
Obviously you should include code to stop if the file can't be found.