How to use R package exams with portuguese accents? - r

When I'm using the package exams to generate questions, I can do it perfectly in english even with special characters. For example, a Rnw question that I can compile with exams package:
<<echo=FALSE, results=hide>>=
## DATA GENERATION
P <- round(runif(n = 1, min = 1000, max = 2000), digits = 2)
S <- round(runif(n = 1, min = P + 500, max = 3000), digits = 2)
## QUESTION/ANSWER GENERATION
i <- round((S - P)/P, digits = 2)*100
#
\begin{question}
Qual \'e a taxa de juros simples obtida por uma aplica\c{c}\~ao de \textdollar $\Sexpr{P}$ que, ap\'os um ano, produz um montante de \textdollar$\Sexpr{S}$?
\end{question}
\begin{solution}
Os juros s\~ao calculados por:
\begin{equation}
S = P(1+i \times n) \Rightarrow S = P + Pin \Rightarrow
\end{equation}
\begin{equation}
Pin = S - P \Rightarrow
i = \frac{S-P}{Pn} \Rightarrow i = \frac{S-P}{P}
\end{equation}
O valor absotulo dos juros \'e $\Sexpr{i}$\%.
\end{solution}
%% META-INFORMATION
%% \extype{num}
%% \exsolution{\Sexpr{fmt(abs(tstat), 3)}}
%% \exname{t statistic}
%% \extol{0.01}
For example, when I need ç I just use \c{c} and so on. BUT, I have been trying to use Rmarkdown instead of Rnw files. And the same example in Rmd:
---
output: pdf_document
---
```{r data generation, echo = FALSE, results = "hide"}
P <- round(runif(n = 1, min = 1000, max = 2000), digits = 2)
S <- round(runif(n = 1, min = P + 500, max = 3000), digits = 2)
i <- round((S - P)/P, digits = 2)*100
```
Question
========
Qual é a taxa de juros simples obtida por uma aplicação de $`r P`
Solution
========
Os juros são calculados por:
\begin{equation}
S = P(1+i \times n) \Rightarrow S = P + Pin \Rightarrow
\end{equation}
\begin{equation}
Pin = S - P \Rightarrow
i = \frac{S-P}{Pn} \Rightarrow i = \frac{S-P}{P}
\end{equation}
O valor absotulo dos juros é `r i`%.
Meta-information
================
extype: num
exsolution: `r round(i, digits = 3)`
exname: Euclidean distance
extol: 0.01
I can compile with RStudio showing the accents correctly:
but when I try:
exams2pdf('file.Rmd', encoding = 'utf8')
it doen't work.
Could someone help me with this issue?

I tried different approaches with the arguments header and inputs of exams2pdf() but none of those gave me the correct output. Also adding LaTeX commands via the YAML header (header-includes) does not work. So I did it the "hard way":
Go to your R library and find the location where the package exams is saved. Inside navigate to the tex folder. There you will find the different templates used by exams. Create a copy of the default template plain.tex and call this duplicate plain_pt.tex. Inside that file you add
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[portuguese]{babel}
to the preamble. Save the file.
The full path on my OSX machine:
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/exams/tex
In Linux can be:
~/R/x86_64-pc-linux-gnu-library/3.3/Resources/library/exams/tex
Now, when calling exams2pdf you can choose your new template with template = 'plain_pt'.
This should also work for other languages by adding the appropriate LaTeX commands.

Thanks to #MartinDabbelJuSmelter for his reply which essentially captures what is going on. However, there are simpler solutions for this. The easiest is:
exams2pdf("file.Rmd", encoding = "UTF-8", template = "plain8")
which leads to the desired output. Now why is this so complicated and why is it so poorly documented?
It is complicated because of the modular structure of the exams package. There are so many different ways to combine the different building blocks that something as easy as this requires two arguments. First, you have to declare that the file.Rmd is in encoding UTF-8. Second, you have to use a template that supports UTF-8. The exams package ships with a simple plain template with UTF-8 enabled.
There are not more LaTeX templates in different encodings etc. because we expected that almost all users will want to use their own custom template anyways. For example, to display the name of their university or their course or to use a particular style/font/etc.
If you only have single-choice (schoice) or multiple-choice (mchoice) questions, then there is also exams2nops which offers a standardized format where it is much simpler to use (but also with less customization). For an impression, see:
exams2nops(c("anova.Rmd", "tstat2.Rmd"),
language = "pt", encoding = "UTF-8")
So you cannot use your num question file.Rmd for this. But the big advantage if you turned it into an schoice question would be that you get automatic scanning and evaluation for exams2nops.
So now for the Achilles heel: the poor documentation. In my defense, I have to say that in Section 2.3 (Creating the first exam) of vignette("exams2", package = "exams") the encoding issue is briefly discussed and it is recommended to look at the output of exams_skeleton() to see how this works. So in your case
exams_skeleton(markup = "markdown", encoding = "UTF-8")
should have provided some useful examples.
But arguably this ought to be easier to find. A better documentation web page for exams is high on my wish list - especially for guiding newcomers - but this summer I didn't find the necessary time. Hopefully next year...
P.S.: The following lines at the start of the Rmd file are completely unnecessary and ignored by exams:
---
output: pdf_document
---
The output into which each exercise is rendered is determined by the exams2xyz functions and not the exercise files themselves. For example:
exams2html("foo.Rmd", encoding = "UTF-8", template = "plain8")
The reason for the function (rather than the Rmd file) deciding about this is simple: Users typically want to build a large pool of questions and then might want to use the same question in a PDF file (for a written exam) or for Moodle or for live voting via ARSnova etc. If you had to modify the question pool each time for this (or keep copies) that would be rather cumbersome.

Related

How to add answer specific feedback to dist3.Rmd?

I'm looking at the dist3.Rmd example template from here: http://www.R-exams.org/templates/dist3/. The solution markdown is the general feedback provided after submission. I want to create feedback.
Solution
========
The distance $d$ of $p$ and $q$ is given by
$d^2 = (p_1 - q_1)^2 + (p_2 - q_2)^2$ (Pythagorean formula).
Hence $d = \sqrt{(p_1 - q_1)^2 + (p_2 - q_2)^2} =
\sqrt{(`r p[1]` - `r q[1]`)^2 + (`r p[2]` - `r q[2]`)^2}
= `r round(sol, digits = 3)`$.
\
```{r distplot, echo = FALSE, results = "hide", fig.path = "", fig.cap = ""}
par(mar = c(4, 4, 1, 1))
plot(0, type = "n", xlim = c(0, 6), ylim = c(0, 6), xlab = "x", ylab = "y")
grid(col = "slategray")
points(rbind(p, q), pch = 19)
text(rbind(p, q), c("p", "q"), pos = c(2, 4))
lines(rbind(p, q))
lines(c(p[1], p[1], q[1]), c(p[2], q[2], q[2]), lty = 2)
```
If the answer choice is correct, I'd like the general feedback to popup and if the answer is wrong, I'd like for the pythagorean formula and the image prompt to show up but not the calculation. How can I accomplish this?
Given your jargon about "general feedback" I assume this is related to Moodle and the exams2moodle() interface in R/exams.
I tried to find out whether the feature you describe can be specified using Moodle XML format but was not successful. So at the moment this is certainly not possible in R/exams and I'm not sure whether it would be possible in Moodle XML. If anyone is aware of a solution in Moodle XML, I would be interested and could check whether it would be possible to add this to exams2moodle().
Update: Following the discussion in the comments with #ArvindMurali I briefly discuss here how it is possible to include images in the specific feedback from the "solution list". However, I still don't see how to separate specific and general feedback between different iterations of answering the question.
If you make a copy of dist3.Rmd to, say, dist4.Rmd you just need to modify two lines. In the options for the r distplot code chunk in line 35, add fig.show = "hide". And in the r solutionlist chunk in line 46 replace the answerlist(...) command with:
answerlist(ifelse(sc$solutions,
"This is correct!",
"This is not correct, please consider: <br/> ![](distplot-1.png)"),
markup = "markdown")
For preparing this for Moodle you then need to use pluginfile = FALSE so that the image is really embedded directly into the specific feedback (rather than via Moodle's plugin file declaration).
set.seed(1)
exams2moodle("dist4.Rmd", pluginfile = FALSE)
Then, the specific feedback for each incorrect item will display the plot from the r distplot chunk.
The formatting is not great but it works - so far so good.
The problem is that in addition to this specific feedback, the general feedback will also be displayed at the end - always, as far as I can see. If there were a way to delay this in Moodle, then I could check whether it is possible to interface this in R/exams.

R Markdown render fails knit with mlogit, object not found, but code chunks work

I have done a basic search around the site (e.g. R Knit Markdown code chunk: "object not found"), but I don't think I have found anything that fixes my problem, or at least explains why my problem occurs.
There are only a few code chunks in my .rmd which come quite verbatim from https://cran.r-project.org/web/packages/mlogit/vignettes/e1mlogit.html
The first is to load data
rm(list = ls())
library(mlogit)
data("Heating", package = "mlogit")
H <- mlogit.data(Heating, shape = "wide", choice = "depvar", varying = c(3:12))
Then I fit the model, but I use ref_level_var instead of any specific string "gr"
ref_level_var <- "gr"
mc <- mlogit(formula = depvar ~ ic + oc, data = H, reflevel = ref_level_var)
The odd part comes when I try
head(predict(mc, newdata = H))
Now because I require my files to be knit to two different formats (solution via Knit one markdown file to two output files), I use the following knit in my header for the .rmd
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile, encoding = encoding, output_format = c("html_document", "pdf_document"))})
However, this results in the following error
Error in model.frame.mFormula(formula = depvar ~ ic + oc, data = structure(list(: object 'ref_level_var' not found
Obviously, it seems that somehow ref_level_var is not visible to the knitting session, despite there being a ref_level_var <- "gr" line somewhere. Why does this error occur, and how can I fix it?
Note that the error is very odd, because replacing the whole knit line with output: html_document results in no errors.

How to output values of R variables in an inline LateX equation in R Markdown (i.e. dynamically updated)

I am unable to find a way to implement r code into an inline LateX equation in R markdown. The goal is to not have to hard code the values of my variable 'values' if they were to change.
Given:
values <- c(1.4, 2.5, 7, 9)
avg <- sum(values)/length(values)
avg
My current approach was to just copy and paste the values of my R variable into the LaTeX inline equation as such:
The average of $values$ is $\hat{v} = \frac{1.4 + 2.5 + 7 + 9}{4} = 4.975$
But this is cumbersome even with such a trivial example.
Using inline r code with r values[1] does not work inside of a LateX equation in R Markdown.
---
title: Inline LaTeX using \textsf{\textbf{R}} variables
output: pdf_document
---
```{r, echo=FALSE}
# set variables
set.seed(1)
values <- sample(10:100, sample(3:5))/10
lv <- length(values)
avg <- sum(values)/lv
```
\begin{center}
The average of $values$ is
$\hat{v} = \frac{`r paste(values, collapse=" + ")`}{`r lv`} = `r round(avg, 3)`$.
\end{center}
If you same that as a .rmd file and render it you should get something like

How to find byte sizes of R figures on pages?

I would like to monitor the basic quality of the figures produced in R on individual pages such as byte size of each page,...
I can now do only quality assurance of average pages, see the following chapter about it.
I think there must be something builtin for the task than average measures.
Code which produces 4 pages in Rplots.pdf where I would like to know the byte size of each page in an output here; any other statistics of the page outputs is also welcome;
you can get the basic memory monitoring by objects here but I would like it to correspond to the outputs in PDF
# https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/plot.html
require(stats) # for lowess, rpois, rnorm
plot(cars)
lines(lowess(cars))
plot(sin, -pi, 2*pi) # see ?plot.function
## Discrete Distribution Plot:
plot(table(rpois(100, 5)), type = "h", col = "red", lwd = 10,
main = "rpois(100, lambda = 5)")
## Simple quantiles/ECDF, see ecdf() {library(stats)} for a better one:
plot(x <- sort(rnorm(47)), type = "s", main = "plot(x, type = \"s\")")
points(x, cex = .5, col = "dark red")
## TODO summarise here the byte size of figures in the figures (1-4)
# Output: Rplot.pdf where 4 pages; I want to know the size of each page in bytes
I am currently doing the basic quality assurance in command-line but would like to move some of it to R, to observe bugs faster.
Expected output: byte size, for instance like 4th column of ls -l
To get bytesize of average individual page in an output document
Limitations
Requirement of the homogeneity of the data in pages. This method only works if the pages are all from the same sample.
Otherwise, it is troublesome because it is only average, not describing then the individual phenomenons.
Other possible weaknesses
PDF-elements and meta data. Consider PDF-file as whole, not focusing on the graphic objects itself. So this limits the absolute value use because the filesize contains also headers and other meta data which are not about the graphic objects.
Code
filename <- "main.pdf"
filesize <- file.size(filename)
# http://unix.stackexchange.com/q/331175/16920
pages <- Rpoppler::PDF_info(filename)$Pages
# print page size (= filesize / pages)
pagesize <- filesize / pages
## data of example file
num 7350960
int 62
num 118564
Input: just any 62-pages document
Output: average individual page size (118564)
Testing and's answer
Output but you cannot change the input easily to your wanted PDF-file
files size_bytes
[1,] "./test_page_size_pdf/page01.pdf" "4,123,942"
[2,] "./test_page_size_pdf/page02.pdf" " 4,971"
[3,] "./test_page_size_pdf/page03.pdf" " 4,672"
[4,] "./test_page_size_pdf/page04.pdf" " 5,370"
Input: just any 64-pages document
Expected output: 67 (= 64 + 3) pages, not 4 analysed
R: 3.3.2
OS: Debian 8.5
Download and install the pdftk utility if it is not already on your system and then try one of the following alternatives this from within R.
1) It will return a data frame with the page file sizes in bytes and other information.
myfile <- "Rplots.pdf"
system(paste("pdftk", myfile, "burst"))
file.info(Sys.glob("pg_*.pdf"))
It will also generate a file doc_data.txt with some miscellaneous information that may or may not be of interest.
1a) This alternative will not generate any files. It will simply return the character sizes of the pages as a numeric vector.
myfile <- "Rplots.pdf"
pages <- as.numeric(read.dcf(pipe(paste("pdftk", myfile, "dump_data")))[, "NumberOfPages"])
cmds <- sprintf("pdftk %s cat %d output - | wc -c", myfile, seq_len(pages))
unname(sapply(cmds, function(cmd) scan(pipe(cmd), quiet = TRUE)))
The above should work if pdftk and wc are on your path. Note that on Windows you can find wc in the Rtools distribution and is typically at "C:\\Rtools\\bin\\wc" once Rtools is installed.
2) This alternative is similar to (1) but uses the animation package:
library(animation)
ani.options(pdftk = "/path/to/pdftk")
pdftk("Rplots.pdf", "burst", "pg_%04d.pdf", "")
file.info(Sys.glob("pg_*.pdf"))
To measure the size of each page in a pdf-file I suggest this:
test_size <- TRUE
pdf_name <- "masterpiece"
if(test_size){
dir.create("test_page_size_pdf")
pdf_address <- paste0("./test_page_size_pdf/page%02d.pdf")
} else { pdf_address <- paste0("./", pdf_name, ".pdf")}
pdf(pdf_address, width=10, height=6, onefile=!test_size)
par(mar=c(1,1,1,1), oma=c(1,1,1,1))
plot(rnorm(10^6, 100, 5), type="l")
plot(sin, -pi, 2*pi)
plot(table(rpois(100, 5)), type = "h", col = "red", lwd = 10,
main = "rpois(100, lambda = 5)")
plot(x <- sort(rnorm(47)), type = "s", main = "plot(x, type = \"s\")")
points(x, cex = .5, col = "dark red")
dev.off()
if(test_size){
files <- paste0("./test_page_size_pdf/", list.files("./test_page_size_pdf/"))
size_bytes <- format(file.size(files), big.mark = ",")
file.remove(files)
file.remove("test_page_size_pdf")
cbind(files, size_bytes)
}
The size of a pdf-page in R depends on three things: the content of the plot(), the options used in the pdf() function and the plotting options which are here defined in par().
All this is difficult to estimate. You mention also that you like to have something similar to the shell function ls, which run on files as well. So in this solution I create a temporary folder dir.create() in which we save every page of the pdf separately in a file. We implement this with the option onefile. When the plotting is finish every pdf-page-file as well as the temporary folder will be deleted. And you can see the result in the console.
If you are finish with the testing and want the result in a single file you just have to change in the first line of this script the variable test_size <- FALSE. By the way; I have some doubt that the size of a page is a proxy for the quality of an image. Pdf is a vector format, so the size correspondent with the number of elements: see the size of the first page in my example where I plot 1mio points.

Dynamic references to figures in a R comment within Sweave document

I would like to find a way to use the LaTeX \ref{} markup to comment in the R code within a Sweave .Rnw file. Here are two examples, one in print
http://cm.bell-labs.com/cm/ms/departments/sia/project/nlme/UGuide.pdf
and one to use to work with:
The .Rnw file
% File: example.Rnw
\documentclass{article}
\usepackage{fullpage}
\usepackage{graphics}
\usepackage{Sweave}
\usepackage[margin = 10pt, font=small, labelfont={bf}]{caption}
\begin{document}
Here is an example file to show what I want to do. I would like to figure out how to use the \LaTeX\ reference command to reference a figure being generated by R code. Note in the R code, in a comment there is a reference to the figure, but of course the output file shows a verbatim copy of the \LaTeX\ markup. Does anyone know how to get something for Figure \ref{fig2}?
<< example plot >>=
library(reshape)
library(ggplot2)
n <- 100
lambda <- 1 / 3
x <- seq(0, qexp(0.999, rate = lambda), length = n)
q1.a <- data.frame(x = x,
f = dexp(x, rate = lambda),
F = pexp(x, rate = lambda))
q1.a <- melt(q1.a, id.vars = 'x')
g <- ggplot(q1.a) + # Produces \ref{fig1}
aes(x = x, y = value) +
geom_line() +
facet_wrap( ~ variable, scale = "free_y")
ggsave(g, filename = "example1.jpeg")
#
\begin{figure}[h]
\centering
\includegraphics[width = 0.48\textwidth]{./example1}
\caption{Exponential Distribution based plots.}
\label{fig1}
\end{figure}
Here is more of what I would like to see:
<< example plot 2 >>=
ggsave(g + geom_point(), filename = "example2.jpeg") # Produces Figure 2
#
\begin{figure}
\centering
\includegraphics[width = 0.48\textwidth]{./example2}
\caption{Exponential Distribution based plots with points and lines.}
\label{fig2}
\end{figure}
\end{document}
and the pdf is build with the R commands
Sweave(file = 'example.Rnw',
engine = "R",
keep.source = 'TRUE',
echo = 'TRUE',
results = 'verbatim')
tools::texi2dvi(file = "example.tex",
pdf = TRUE,
clean = TRUE)
Any insight on how do this would be great.
Here is one way to solve this issue by redefining the Sinput environment in which source code is wrapped by Sweave. By default, it is a simple verbatim environment which is not processed by latex for tokens. The trick is to redefine it to use the alltt environment which allows some tokens to be parsed inside the alltt environment. Note that this might lead to unwanted side effects that I am not aware of, so use with caution!
Here is a reproducible example that works. If you compile it, you will generate a file where ref{fig1} is replaced by the figure number.
\documentclass{article}
\usepackage{Sweave}
\usepackage{alltt}
\renewenvironment{Sinput}{\begin{alltt}}{\end{alltt}}
\begin{document}
In this document, we will create a plot using `R`, and reference its position in
the source code.
<<produce-plot, results = hide>>=
pdf('example1.pdf')
plot(1:10, 1:10) # Produces Figure \ref{fig1}
dev.off()
#
\begin{figure}
\includegraphics{example1.pdf}
\caption{Figure 1}
\label{fig1}
\end{figure}
\end{document}

Resources