Forum: support
Monitor Forum | Start New ThreadRE: bordermatrix in exams2html / exams2blackboard [ Reply ] By: Thomas Farrar on 2021-04-29 13:45 | [forum:48939] |
Ah... I wasn't aware of that function and it looks like it would have been easier! Thank you. When I was creating my own workaround, pdftools::pdf_convert was behaving better for me than magick::image_convert. However, that may have been due to me not knowing the ideal function arguments to use. |
RE: bordermatrix in exams2html / exams2blackboard [ Reply ] By: Achim Zeileis on 2021-04-29 10:31 | [forum:48938] |
This is similar to what exams::tex2image() does which supports a few further options including producing SVG rathern than PNG. Maybe that would work for you as well? |
RE: bordermatrix in exams2html / exams2blackboard [ Reply ] By: Thomas Farrar on 2021-04-29 10:25 | [forum:48937] |
Just an epilogue... it turns out that the above still did not display correctly. I ended up resorting to a rather clunky but effective workaround as follows: - I wrote a function (see below) that writes the matrix to a PDF file (I used kbordermatrix because I need to write matrices with fractional elements AND row and column labels, and these display better in kbordermatrix) - I used pdftools::pdf_convert to convert the PDF to a png (one may need to increase the dpi argument from the default of 72) - Applied exams::include_supplement - Used \includegraphics to include the matrix in the question as a PNG. It does then display nicely in the browser. bordermatrixPDF <- function(A, Anametex = "P", filename = "mybordermatrix", filepath) { # A is an R matrix object # Anametex is the name of A in LaTeX (will be put inside \mathbf{}) # You should have kbordermatrix.sty saved in filepath folder # this can be downloaded from https://ctan.org/pkg/kbordermatrix?lang=en x <- paste0("\\documentclass[varwidth=true, border=10pt]{standalone} \\usepackage{amsmath} \\usepackage{", filepath, "/kbordermatrix} \\begin{document} \\LARGE \\[ \\mathbf{", Anametex, "} = \\kbordermatrix{ & ", paste0(colnames(A), collapse = " & "), "\\\\ ", paste(vapply(1:nrow(A), function(i) { paste0(paste0(c(rownames(A)[i], A[i, ]), collapse = " & "), "\\\\ ") }, ""), collapse = " "), "} \\] \\end{document}") write(x, file = paste0(filename, ".tex")) tinytex::xelatex(file = paste0(filename, ".tex")) } |
RE: bordermatrix in exams2html / exams2blackboard [ Reply ] By: Achim Zeileis on 2021-03-13 01:25 | [forum:48817] |
Cool, thanks for sharing! |
RE: bordermatrix in exams2html / exams2blackboard [ Reply ] By: Thomas Farrar on 2021-03-12 08:56 | [forum:48816] |
It is probably a bit of overkill, but I expect to be using it many times. I have written an R function that does a reasonably good job of formatting a bordermatrix like the above, taking an R matrix (with labels in its dimnames attribute) as its argument. It is designed to adjust for different matrix sizes as well as for different lengths (# of digits) in the matrix elements. I have only tested it with 2x2, 3x3 and 4x4 matrices, and decimal elements of up to four decimal places. The function has R package magrittr as a dependency, and the LaTeX package amsmath is needed. bordermatrix <- function(A) { maxellength <- apply(nchar(A), 2, max) phantomsbefore <- paste0("\\\\phantom{", strrep("0", as.integer(maxellength / 3)), "}") phantomsafter <- paste0("\\\\phantom{", strrep("0", as.integer(maxellength / 3)), "}") phantomsbefore[1] <- paste0("\\\\phantom{", strrep(".", maxellength[1] - 3), "}") phantomsbefore[nrow(A)] <- paste0("\\\\phantom{", strrep(".", maxellength[nrow(A)] - 3), ".} ") phantomsafter[1] <- paste0("\\\\phantom{", strrep(".", maxellength[1] - 3), ".} ") phantomsafter[nrow(A)] <- paste0("\\\\phantom{", strrep(".", maxellength[nrow(A)] - 3), "}") phantomrow <- paste0(phantomsbefore, dimnames(A)[[2]], phantomsafter) %>% paste(collapse = " & ") paste0("\\\\[ \\\\begin{array}{ccc} & & \\\\begin{array}{", strrep("c", nrow(A)), "}", phantomrow, "\\\\end{array} \\\\\\\\ \\\\mathbf{P} = \\\\hskip-0.8em & \\\\begin{array}{c}", paste(dimnames(A)[[1]], collapse = " \\\\\\\\ "), "\\\\end{array} \\\\hskip-1em & \\\\begin{pmatrix}", vapply(1:nrow(A), function(i) { paste0(paste(A[i, ], collapse = " & "), "\\\\\\\\ ") }, "") %>% paste(collapse = "") %>% substr(start = 1, stop = nchar(.) - 5), " \\\\end{pmatrix} \\\\end{array} \\\\]") } In the chunk, one would source() the script containing the function and define a matrix as follows for instance: P1 <- matrix(data = c(0.1, 0.7, 0.2, 0.3, 0.4, 0.3, 0, 1, 0), nrow = 3, ncol = 3, byrow = TRUE, dimnames = list(0:2, 0:2)) P2 <- P1 %*% P1 P4 <- P2 %*% P2 Then in the question or solution environment, \Sexpr{bordermatrix(P1)} \Sexpr{bordermatrix(P2)} \Sexpr{bordermatrix(P4)} |
RE: bordermatrix in exams2html / exams2blackboard [ Reply ] By: Achim Zeileis on 2021-03-11 16:58 | [forum:48811] |
(a) No worries, I also learned something. (b) Thanks for sharing the extended code. (c) I guess my tolerance for slightly sub-optimal layout in the output in trade-off for simpler LaTeX code is higher than yours ;-) Specifically in R/exams exercises... |
RE: bordermatrix in exams2html / exams2blackboard [ Reply ] By: Thomas Farrar on 2021-03-11 14:37 | [forum:48810] |
Thank you Achim, this is great. It should have occurred to me that this issue was wider than the exams package and therefore that solutions might be had on stackexchange etc. I have just made a couple of tweaks. Putting the "P =" in another column of the outermost array makes it vertically align correctly. I also used \hskip and \phantom to improve horizontal spacing of the row labels and column labels respectively. The arguments of \phantom would need to be modified if the matrix elements were fractions or had more than one decimal place. I may write an R function that generates the LaTeX code for such a pseudo-bordermatrix for a given R matrix object. \[ \begin{array}{ccc} & & \begin{array}{ccc} 0\phantom{.} & \phantom{0}1\phantom{0} & \phantom{.}2\phantom{} \end{array} \\ \mathbf{P} = \hskip-0.8em & \begin{array}{c} 0 \\ 1 \\ 2 \end{array} \hskip-1em & \begin{pmatrix} 0.3 & 0.2 & 0.5\\ 0.4 & 0.5 & 0.1\\ 0.2 & 0.2 & 0.6 \end{pmatrix} \end{array} \] |
RE: bordermatrix in exams2html / exams2blackboard [ Reply ] By: Achim Zeileis on 2021-03-11 08:11 | [forum:48798] |
Interesting, I've never heard of \bordermatrix although it is indeed part of LaTeX. Hence I was surprised that it is not supported by MathJax, not sure why. I've found these two related posts on StackExchange: https://stackoverflow.com/questions/53888339/alternative-to-bordermatrix-for-mathjax?rq=1 https://tex.stackexchange.com/questions/496196/bad-alignment-with-bordermatrix-in-mathjax Based on these it seems that a reasonably simple replacement is a {pmatrix} inside an {array}. The main difficulty is to align the column names from the outer {array} with the columns from the innter {pmatrix}. I have handled this below by including a non-breaking space via ~ before and after the column names. \[ \mathbf{P} = \begin{array}{cc} & \begin{array}{ccc} ~0~ & ~1~ & ~2~ \end{array} \\ \begin{array}{c} 0 \\ 1 \\ 2 \end{array} & \begin{pmatrix} 0.3 & 0.2 & 0.5\\ 0.4 & 0.5 & 0.1\\ 0.2 & 0.2 & 0.6 \end{pmatrix} \end{array} \] This works in exams2pdf() and in exams2html(..., converter = "pandoc-mathjax") and also converter = "pandoc". Only converter = "ttm" fails. The alignment of the "P =" does not look great but it's certainly good enough in order not to confuse students. |
bordermatrix in exams2html / exams2blackboard [ Reply ] By: Thomas Farrar on 2021-03-10 08:48 | [forum:48797] bordermatrix.Rnw (2) downloads |
Hello, I am teaching Markov Chains and normally use \bordermatrix (which is apparently plain TeX albeit not officially documented) in order to place labels of the states outside the transition probability matrix. However, exams2html and exams2blackboard do not compile \bordermatrix correctly. If I use the default converter, the matrix does appear but without brackets around it, which may cause students to confuse the state labels with matrix elements. If I use the "pandoc" or "pandoc-mathjax" converter, it does not compile at all. I have tried to use an array environment instead, but have struggled to place brackets around the matrix elements only. See a couple of attempts in the attached. (I'm not surprised that the multirow attempt fails, since presumably multirow package is not supported by the HTML converters.) Any suggestions for a workaround here? |