Problem with round() function in .Rmd exercise file - r-exams

I have a problem where I create a .Rmd file for an exercise and I include a large number together with the round() function. Here is a minimal example:
```{r data generation, echo = FALSE, results = "hide"}
Value = 12000.555
```
Question
========
temp
Meta-information
================
exname: temp
extype: num
exsolution: `r round(Value, 2)`
extol: 0.01
I try to compile this exercise into an exam using exams2pdf() yielding the following error:
exams2pdf("example.Rmd")
## Warning message: In read_metainfo(file) : NAs introduced by coercion
Why is that? I'm using R/exams version 2.3-6, and R version 3.6.3.

TL;DR: Use fmt(Value, 2) instead of round(Value, 2). This avoids problems with scientific notation (and uses rounding away from zero). See ?fmt for more details.
The reason for the error is actually not the round() function per se, but the fact the R by default uses scientific notation for numbers with a certain number of significant digits (factory-fresh default in R is scipen = 7). Furthermore, the knitr package (employed in the background by R/exams) tries to format this scientific notation nicely. So instead of 12000.56 the knit() function includes 1.200056 × 10<sup>4</sup> in the Markdown file. You can see this when you run xweave("example.Rmd") and then inspect the resulting example.md file. And then the subsequent processing of the exsolution tag hence has problems to convert this back to a number, hence the warning.
To avoid this you could increase the scipen limit within the R code of the exercise, e.g., options(scipen = 999). But this is very technical and tedious. This is one of the reasons why we have written the fmt(...) function that carries out various convenience tasks that have to do with formatting of numbers within R/exams exercises.

Related

Unexplained R failure: Error: attempt to use zero-length variable name

I am trying to specify the size of a plot dynamically in RMarkdown. Because it is a facetted plot with a dynamic number of plots, the aspect ratio needs to change.
I'm using this code:
...
jobs_levels <- 9
```
#### Figure 3.1.1. Effect of Inidivdual Interventions in Living Rooms
```{r figure_3_3_1, fig.height=jobs_levels}
jobs_levels
print(figure_3_3_1)
```
For the sake of simplicity, I've hard coded the jobs_levels (the number of levels in the facetting factor). As you can see, I set the value very clearly,and then use it in the very next code chuck. I can see the value clear as day in the environment. It is 9. But I get this:
Error in eval(ele) : object 'jobs_levels' not found
> ```{r figure_3_3_1, fig.height=jobs_levels}
Error: attempt to use zero-length variable name
When I run this in batch mode, it crashes. Any idea what is going on with this?
I even put in the extra lines:
jobs_levels
to debug. EAch time I run one of those lines with cotrl enter, it evaluates right, but I see the error message again too...
The error message makes it look as though you are trying to evaluate the chunk header as R code. You had
```{r figure_3_3_1, fig.height=jobs_levels}
The first two backticks would be parsed as a zero length variable name, as the error message states.
You can't run R Markdown code as R code, you need to use rmarkdown::render or a related function to run it.

Run a function that requires user interaction in a knitr document

I am using the package Knitr to write a report in latex. I have written the following function in my snippet:
sum <- function(){
n <- as.numeric(readline("Enter any positive integer"))
i <- 1:n; s <- sum(i)
return(s)
}
When I execute it inside the Latex document as:
<<>>
sum()
#
I get this error:
## Enter any positive integer ##
Error in 1:n: NA/NaN argument
How do I fix the snippet?
To be able to input anything interactively, readline() has to be used in an interactive R session, but your Rnw document is compiled in a non-interactive R session (why?)---this is only my guess, since you didn't mention how you compiled the document, and most people probably click the "Knit" button in RStudio, which means the document is compiled in a separate non-interactive R session.
In a non-interactive R session, readline() doesn't allow interactive input, and returns "" immediately, which leads to the error you saw:
> 1:""
Error in 1:"" : NA/NaN argument
If you have any code that requires human interaction (such as inputting numbers), the document has to be compiled in an interactive R session, and the way to do it is to run knitr::knit('your-document.Rnw') in the R console. (For R Markdown users, run rmarkdown::render() instead.)
That said, I don't recommend putting code that requires interaction in a knitr document, because it will make it harder to be reproducible (the result depends on interactive input, which is not predictable).
You may define your function so it doesn't absolutely require human interaction, e.g.,
sum2 <- function(n = as.numeric(readline("Enter any positive integer"))) {
i <- 1:n; s <- sum(i)
return(s)
}
Then if you want to call the function in a non-interactive R session, you can pass a value to the argument n, e.g.,
sum2(10)

Multiple plots in repeated question yields "Error in exm[[dups[j]]] : subscript out of bounds"

When creating worksheets with exams2pdf() from R/exams, I like to repeat an exercise file multiple times to yield different numbers. However, when I include two plots in an exercise (e.g., one in the question and one in the solution) this yields:
Error in exm[[dups[j]]] : subscript out of bounds
A reproducible example is included below.
It works with one plot, and it works if I don't repeat the question. Also, the problem can be avoided by making multiple copies of a simple.Rmd (say simple1.Rmd and simple2.Rmd with different chunk names in each copy) but it seems there should be a better way.
The Rmd file: simple.Rmd
Question
========
A question.
```{r drawit}
x = (-330):330/100
y = dnorm(x)
plot(x,y)
```
Solution
========
Let's redraw...
```{r drawagain}
x2 = (-330):330/100+100
y2 = dnorm(x2,mean=100,sd=1)
plot(x2,y2)
```
Meta-information
============
extype: num
exsolution: 10
exname: calc
And the replication R code:
library("exams")
q1 = "simple.Rmd"
probs = c(q1,q1)
exams2pdf(probs)
The Rmd file will knit fine (with two plots) but running the code above yields the above mentioned
Error in exm[[dups[j]]] : subscript out of bounds
Thanks for reporting this, this is a bug in exams2pdf()! Single duplicated supplement names were already corrected but the case of multiple duplicated supplement names was not. I've just committed a fix to the repository on R-Forge that addresses the issue.
It would be great if you could install the development version of the package from R-Forge to test whether the fix also works correctly on your real use-case. You can install from within R via:
install.packages("exams", repos="http://R-Forge.R-project.org")

How does the PACKAGE argument to .Call work?

.Call seems rather poorly documented; ?.Call gives an explanation of the PACKAGE argument:
PACKAGE: if supplied, confine the search for a character string .NAME to the DLL given by this argument (plus the conventional extension, ‘.so’, ‘.dll’, ...).
This argument follows ... and so its name cannot be abbreviated.
This is intended to add safety for packages, which can ensure by using this argument that no other package can override their external symbols, and also speeds up the search (see ‘Note’).
And in the Note:
If one of these functions is to be used frequently, do specify PACKAGE (to confine the search to a single DLL) or pass .NAME as one of the native symbol objects. Searching for symbols can take a long time, especially when many namespaces are loaded.
You may see PACKAGE = "base" for symbols linked into R. Do not use this in your own code: such symbols are not part of the API and may be changed without warning.
PACKAGE = "" used to be accepted (but was undocumented): it is now an error.
But there are no usage examples.
It's unclear how the PACKAGE argument works. For example, in answering this question, I thought the following should have worked, but it doesn't:
.Call(C_BinCount, x, breaks, TRUE, TRUE, PACKAGE = "graphics")
Instead this works:
.Call(graphics:::C_BinCount, x, breaks, TRUE, TRUE)
Is this simply because C_BinCount is unexported? I.e., if the internal code of hist.default had added PACKAGE = "graphics", this would have worked?
This seems simple but is really rare to find usage of this argument; none of the sources I found give more than passing mention (1, 2, 3, 4, 5)... Examples of this actually working would be appreciated (even if it's just citing code found in an existing package)
(for self-containment purposes, if you don't want to copy-paste code from the other question, here are x and breaks):
x = runif(100000000, 2.5, 2.6)
nB <- 99
delt <- 3/nB
fuzz <- 1e-7 * c(-delt, rep.int(delt, nB))
breaks <- seq(0, 3, by = delt) + fuzz
C_BinCount is an object of class "NativeSymbolInfo", rather than a character string naming a C-level function, hence PACKAGE (which "confine(s) the search for a character string .NAME") is not relevant. C_BinCount is made a symbol by its mention in useDynLib() in the graphics package NAMESPACE.
As an R symbol, C_BinCount's resolution is subject to the same rules as other symbols -- it's not exported from the NAMESPACE, so only accessible via graphics:::C_BinCount. And also, for that reason, off-limits for robust code development. Since the C entry point is imported as a symbol, it is not available as a character string, so .Call("C_BinCount", ...) will not work.
Using a NativeSymbolInfo object tells R where the C code is located, so there is no need to do so again via PACKAGE; the choice to use the symbol rather than character string is made by the package developer, and I think would generally be considered good practice. Many packages developed before the invention of NativeSymbolInfo use the PACKAGE argument, if I grep the Bioconductor source tree there are 4379 lines with .Call.*PACKAGE, e.g., here.
Additional information, including examples, is in Writing R Extensions section 1.5.4.

Can R help manuals have latex math in them?

I am working on an R package and I am using the package Roxygen2 to write the help manuals for my R functions. What I would like to know is if it is possible to use latex for math equations in the manual pages?
For example, if I had a function called add2 that did the following:
add2 = function(x,y){
z = x+y
return(z)
}
And using Roxygen2 documentation I had the following:
##' #include add2.R
{}
##' Compute the sum of x_1 and x_2
##'
##' Computes the sum of x_1 and x_2
##'
##' #param x_1 number of guys
##' #param x_2 number of girls
##' #return The sum of the two values x_1 and x_2
##'
##' #example examples/adding.R
##' #export
##' #author Name
And this works for me, but this displays x1 and x2 as x_1 and x_2 in the help manual whereas I would like for it to look like latex math and actually have the subscripts on x, i.e., $x_1$ and $x_2$ in latex.
Is there any way to do this or does R not accomodate this?
Sort of. Use something like \eqn{x_1} if you want use the (unprocessed) version of the LaTeX markup in plain-text output (alternately you could say something like \eqn{x_1}{x1}). The "sort of" part is that I'm not sure offhand for which particular output formats the LaTeX processing will be done -- for example, I'm guessing that the HTML-formatted version of output you would see in (e.g.) an RStudio documentation pane would not respect this markup. (The LaTeX markup definitely will be used in the PDF versions of the manual, which I almost never look at ...)
I'm going to go ahead and quote from the Mathematics section of Writing R Extensions ...
Mathematical formulae should be set beautifully for printed documentation yet we still want something useful for text and HTML online help. To this end, the two commands \eqn{latex}{ascii} and \deqn{latex}{ascii} are used. Whereas \eqn is used for “inline” formulae (corresponding to TeX’s $…$), \deqn gives “displayed equations” (as in LaTeX’s displaymath environment, or TeX’s $$…$$). Both arguments are treated as ‘verbatim’ text.
Both commands can also be used as \eqn{latexascii} (only one argument) which then is used for both latex and ascii. No whitespace is allowed between command and the first argument, nor between the first and second arguments.
The following example is from Poisson.Rd:
\deqn{p(x) = \frac{\lambda^x e^{-\lambda}}{x!}}{%
p(x) = \lambda^x exp(-\lambda)/x!}
for \eqn{x = 0, 1, 2, \ldots}.
As of 2020-05-08, the mathjaxr package, by Wolfgang Viechtbauer, is on CRAN. It
Provides 'MathJax' and macros to enable its use within Rd files for rendering equations in the HTML help files.
From the README file:
[After installing the package, editing the package DESCRIPTION file appropriately, and adding \loadmathjax{} to the Rd file ... a]n inline equation can then be added with the \mjeqn{latex}{ascii} macro, with the LaTeX commands for the equation given between the first set of curly brackets (which will be rendered in the HTML and PDF help pages) and the plain-text version of the equation given between the second set of curly brackets (which will be shown in the plain text help). With the \mjdeqn{latex}{ascii} macro, one can add ‘displayed equations’ (as in LaTeX’s displaymath environment).
Quoting O'Reilly's "R Packages" by Hadley Wickham:
You can use standard LaTeX math (with no extensions). Choose between either inline or block display:
\eqn{a + b}: Inline equation
\deqn{a + b}: Display (block) equation
So, using \eqn and \deqn is the recommended and official way.

Resources