Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calling knitr within a function

Tags:

r

knitr

r-mosaic

I have been using knitr, R markdown, and pandoc to create beamer presentations/lectures for a course I'll be teaching in the fall. I've written a short R script to automate the process (analogous to a `make' file), which involves:

  1. knitting a .Rmd file;
  2. Calling pandoc to create a .tex file;
  3. Compiling the .tex file;
  4. Cleaning things up (deleting unnecessary files), etc.

Everything seems to work quite well, with one exception (to date). I've got one lecture that seems to "knit" well only when I call the knit function directly. When I try to use my make function to knit the .Rmd file, certain R objects are not recognized. I've included a short example, below, to illustrate the problem:

I created a file called "test.Rmd" with a single code chunk (below):

## Simulation

```{r test, comment=NA, message=FALSE, warning=FALSE}
library(mosaic)
obs<-c(25, 22, 30, 40) # Number of observations in each category
Ais<-c(0.34, 0.101, 0.104, 0.455) # Total Accreage (NUll proportions)
e.count<-Ais*117 # Expected Counts
test.stat<-sum((obs-e.count)^2/(e.count)) #Test statistic = 43.6
rand.dist<-do(1000)*{ 
  # Randomization Distribution
  new.dat<-sample(1:4, replace=TRUE, size=117, prob=Ais) # Sample with Prob = Null pi's
  new.obs<-tally(~new.dat) # Simulated counts
  chi.sq<-sum((new.obs-e.count)^2/e.count) # Simulated test statistic
}
```

This file "knits" fine if I type knit("test.Rmd"). However, if I create a function called my.knit<-fucntion(){knit("test.Rmd")}, and use this function to do the knitting by typing my.knit(), I get an error message in the output that states:

Error: object 'Ais' not found

Any idea why calling "knit" from another function would change the behavior of the code?

----------------- Update on 5/1/2014 ----------------------

I tested the code again, this time putting "(" and ")" around the Ais. Again, things work fine if I type knit("test.Rmd"), but not when using my.knit(). Here is the output in the .md file when I type my.knit():

## Simulation



```r
library(mosaic)
obs <- c(25, 22, 30, 40)  # Number of observations in each category
(Ais <- c(0.34, 0.101, 0.104, 0.455))  # Total Acreage (NUll proportions)
```

```
[1] 0.340 0.101 0.104 0.455
```

```r
e.count <- Ais * 117  # Expected Counts
test.stat <- sum((obs - e.count)^2/(e.count))  #Test statistic = 43.6
rand.dist <- do(1000) * {
    # Randomization Distribution
    new.dat <- sample(1:4, replace = TRUE, size = 117, prob = Ais)  # Sample with Prob = Null pi's
    new.obs <- tally(~new.dat)  # Simulated counts
    chi.sq <- sum((new.obs - e.count)^2/e.count)  # Simulated test statistic
}
```

```
Error: object 'Ais' not found
```

Its strange since I have created 10 or so other presentations using this approach without a problem. Hadley, thanks for the suggestion to look into the rmarkdown package. I'm using RStudio, and recognize that there is built in functionality for accomplishing many of my goals. The one advantage of how I have things currently set up is that I can use a header file (in latex) common to all presentations & then just use \includeonly to keep the pieces I want for the lecture on any given day.

like image 611
ECOSTATS Avatar asked Sep 30 '22 22:09

ECOSTATS


1 Answers

According to my experience, this problem probably reveals a bug in the mosaic package. I'm not familiar with this package, but here is a minimal reproducible example without knitr:

local({
  library(mosaic)
  foo = 5
  do(10) * {
    mean(foo + rnorm(100))
  }
})

It gives errors as below:

                                                          result
1  Error in eval(expr, envir, enclos) : object 'foo' not found\n
2  Error in eval(expr, envir, enclos) : object 'foo' not found\n
3  Error in eval(expr, envir, enclos) : object 'foo' not found\n
4  Error in eval(expr, envir, enclos) : object 'foo' not found\n
5  Error in eval(expr, envir, enclos) : object 'foo' not found\n
6  Error in eval(expr, envir, enclos) : object 'foo' not found\n
7  Error in eval(expr, envir, enclos) : object 'foo' not found\n
8  Error in eval(expr, envir, enclos) : object 'foo' not found\n
9  Error in eval(expr, envir, enclos) : object 'foo' not found\n
10 Error in eval(expr, envir, enclos) : object 'foo' not found\n
Warning message:
In mclapply(integer(n), function(...) { :
  all scheduled cores encountered errors in user code

I believe do and * should work when they are in a separate environment, i.e. they should not just work in the global environment. As long as the mosaic developers can fix this problem, your function should work.

If you do not want to bother anybody or wait for the problem to be fixed, you can surely call knit() with the global environment, e.g.

knit(..., envir = globalenv())

By default, envir = parent.frame(), which does not work for mosaic at the moment.

like image 134
Yihui Xie Avatar answered Oct 03 '22 16:10

Yihui Xie