My suggestion is real statistics with R integrated with knitr, nor only because is easier make any calculus and will be more exact, including make the plots, but mainly because can extract easily data or results of the R side and insert automatically in the LaTeX text in each compilation.
Therefore, if you make a problem with data generated randomly, you can obtain not only a different plot in each compilation, but also a complete rewrite of your text. If you have 100 students, you need a single document compiled 100 times to obtain 100 different problems and solutions. Except if you use set.seed()
the document will completely different in each compilation, but always correct (or always wrong in the same sense, by your fault).
An example:
\documentclass[twocolumn]{article}\usepackage{parskip,booktabs}\usepackage[columnsep=1cm]{geometry}\begin{document}<<data, echo=F, results="asis">>=# set.seed(34) # add this to NOT change the problemsubject <- "weight in versus height ($y$)"vars <- list("kg","cm")d <- data.frame( x = sort(round(runif(20, min = 45 , max = 99),1)), y = sort(round(jitter(runif(20, min = 155, max = 195),amount=10),1))) @\section*{The problem:} We have a set of fake data of \Sexpr{subject} with $x$ values between \Sexpr{combine_words(range(d$x))} \Sexpr{vars[1]} and $y$ values in the range of \Sexpr{combine_words(range(d$y))} \Sexpr{vars[2]}, paired as showed in the table. Questions: \begin{enumerate}\item What is the Pearson $r$ coefficient? \item There is a significant correlation between $x$ an $y$? \item What is the intercept and the slope of the regression line?\end{enumerate}<<kable, echo=F, results="asis">>=TheTable <- kable(d, caption="The table.", booktabs = T)kableExtra::kable_styling(TheTable, latex_options = "hold_position")@\newpage\section*{The solution:} <<model,echo=F>>=model <- lm(y ~ x, data = d)cortest <- cor.test(d$x,d$y)@\begin{enumerate}\item The \Sexpr{cortest$method} test show a coefficient of \mbox{$r = \Sexpr{round(cortest$estimate,2)}$}. \item This coefficient have a signification of \mbox{$p =\Sexpr{signif(cor.test(d$x,d$y)$p.value,2)}$}. \item The regression line have an intercept of about \Sexpr{signif(coef(model)[1],2)} and a slope of about \Sexpr{signif(coef(model)[2],2)}.\end{enumerate}Ok, for the shake of of accuracy, the exact equation is: \[ y = \Sexpr{coef(model)[1]} + \Sexpr{coef(model)[2]} x \]That plotted in nice LaTeX look like this: <<plot,echo=F,fig.cap="The plot.",fig.pos="h", fig.width = 4, fig.height = 4, out.width = "\\linewidth",dev="tikz">>=plot(d$x, d$y, xlab = "X values", ylab = "Y values", pch = 19, col = "blue")abline(model, col = "red", lwd = 2,cex=2)coefficients <- coef(model)slope <- coefficients[2]intercept <- coefficients[1]text( x = min(d$x) + 20, y = max(d$y) - 5, labels = paste0("y = ", round(intercept, 3)," +" , round(slope, 3),"x"))@\end{document}