Make R Markdown code blocks into math mode - r-markdown

I would love to use R Markdown to generate homework and exam solutions, but I would prefer to have them more readable to non-coders.
I there a way that I can pass the ECHO output through math mode? That is I would love to have an ECHO that looks more "inline" and less like code. I can see how to hide it, but in the R Markdown Reference Guide I don't see an option to remove the "code block" and wrap each line in $$ (or wrap in anything). Is there a way to do this?
Here is an example. This solution has all the meat, but may be a little intimdating to some students (this is not an R course).
8-22 ...
a. ...
```{r part_a}
D_0 = 2.40
g = 0.06
r = 0.12
V = D_0*(1 + g)/(r - g)
V
```
Instead, I would love to see something more like the following.^[I appreciate that I can generate this output with some cutting and pasting and a text editor, I am just trying to find the most efficient solution, since this is likely something that I will do more than once or twice.]
8.22 ...
a. ...
$$ D_0 = 2.40 $$
$$ g = 0.06 $$
$$ r = 0.12 $$
$$ V = D_0 \times (1 + g)/(r - g) = 2.40 \times (1 + 0.06)/(0.12 - 0.06) = `r V`$$

I have a partial answer. I don't yet know how to replace variable x with its value so that a can print the formula with variables, replaced by numbers. But I can generate the "math code" block so that I can solve the problem and generate the pretty solution without a lot of cut and paste.
Here is an example .Rmd file.
---
author: Richard Herron
title: Homework Solutions
---
8-22 ...
a. ...
There are three parts to this solution.
1. write the equations to solve the problem in R-readable strings.
2. loop over the list and `eval(parse())` the equation strings
3. wrap strings in `$$ $$` with `cat(paste0())`
Chunks should be set to `echo=FALSE` and `results="asis`. You may need to suppress some function output with `invisible()`.
```{r part_a, echo=FALSE, results="asis"}
# just to make sure my eval below works
rm(list=ls())
# store solution as a list of character equations
solution <- list(
"D_0 = 2.40",
"g = 0.06",
"r = 0.12",
"V = D_0*(1 + g)/(r - g)"
)
# "solve" problem
for (i in seq_along(solution)) eval(parse(text=solution[[i]]))
# display solution as math
cat(paste0("$$", solution, "$$"), sep="\n")
```
Because of the `eval()` loop in the first chunk I can say that $V = `r V`$ in the text that follows.
And here is an outer file that convert each .Rmd file into a .pdf.
# load `render` and set working directory
setwd("C:/Users/Richard/Dropbox/Babson College/SME 2021 for 2015 fall/Homework")
# loop over all Rmd files
require(rmarkdown)
require(tools)
files <- list.files(path=".", pattern="*.Rmd")
roots <- sapply(files, file_path_sans_ext)
namesIn <- paste0("", roots, ".pdf")
namesOut <- paste0("", roots, ".pdf")
# solutions
myPdf <- pdf_document(
fig_caption=TRUE,
keep_tex=TRUE,
pandoc_args=c(
"--variable=classoption:fleqn",
"--variable=classoption:twocolumn",
paste0("--metadata=date:", format(Sys.time(), "%B %d, %Y"))
)
)
lapply(files, FUN=render, output_format=myPdf)
mapply(file.rename, namesIn, namesOut)
Which yields this pdf.

Related

Word count in Quarto

I would love a convenient and easy way to print my word count automatically in quarto and stumbled across this nice add-in from Ben Marwick:
https://github.com/benmarwick/wordcountaddin
It is sound for rmarkdown and I presumed it should be no issue with quarto too. However, when I use the add-in, though it can count out the number of words within my RStudio session, it doesn't print it in my final pdf format and just returns [1] NA.
{r, #wordcountdev, message = FALSE, warning = FALSE, echo = FALSE}
wordstats <- wordcountaddin:::text_stats('CMI Write Up.qmd')
words <- substr(wordstats[3], start=19, stop=30)
print(words)
I don't understand what is going on here, it is seemingly simple, would anyone know of a better way to achieve what I'm trying?
You could take a look at the wordcounts pandoc filter, e.g. as a starting point it prints the number of words in the body to the console while rendering:
---
format: html
filters: [wordcounts.lua]
---
Hello there, how many words are in the body?
Or: You can use the development version (devtools::install_github("benmarwick/wordcountaddin", type = "source", dependencies = TRUE)) of the above mentioned package:
---
format: html
---
```{r}
#| echo: false
#| label: wordstats
#| warning: false
#| message: false
wordcount <- wordcountaddin::text_stats('wordcount.qmd')
words <- substr(wordcount[3], start=19, stop=30)
```
Hello there, how many words are in the body?
There are `r words` words in the whole document.

Equivalent to `code-line-numbers` for output in Quarto for revealjs slides

I am using Quarto to produce some revealjs slides using RStudio and have been using the code-line-numbers option to selectively highlight lines of code. For instance:
```{r, echo = TRUE}
#| code-line-numbers: "1|3"
x <- 1
y <- 2
x + y
x * y
```
Allows me to highlight the first and third lines of code in the presentation.
I would like to additionally be able to highlight certain lines in the output. For instance, if I wanted to only highlight the result of x+y but not x*y, is there a way of doing so? I wondered if there was an option for output-line-number or similar that might have the desired effect, but couldn't find anything like this.
Any pointers appreciated!
A possible way to do this could be based on using pandoc Lua filter.
Here I have created a chunk-option output-line-numbers to specify which output lines to highlight (works just as code-line-numbers chunk option), but please note that you must have to use class-output: highlight to get this line specific highlighting on chunk output.
---
title: "Output Line highlight"
format: revealjs
filters:
- output-line-highlight.lua
---
```{r, echo = TRUE}
#| code-line-numbers: "1"
#| class-output: highlight
#| output-line-numbers: "2"
for (i in 1:3) {
print("This is some random line")
}
```
output-line-highlight.lua
function highlight(line_number)
local highlighter = {
CodeBlock = function(block)
if block.classes:includes('highlight') then
block.classes:insert('has-line-highlights')
block.attributes["code-line-numbers"] = line_number
return block
end
end
}
return highlighter
end
function Div(el)
if FORMAT == 'revealjs' then
if el.classes:includes('cell') then
line_number = tostring(el.attributes["output-line-numbers"])
return el:walk(highlight(line_number))
end
end
end

Rmarkdown - python inline code in Rmarkdown

I am using Rmarkdown with python. What is the equivalent of the R inline code for python?
Example, in https://rmarkdown.rstudio.com/lesson-4.html I can do
``r x`
to display the value of x in the text. but If I do
``python x`
I just get the text python x
Not sure whether this is possible. All examples I have found use R inline code like so `r py$x` to achieve that. See e.g. the rmarkdown cookbook.
With this workaround, it's possible:
```{r setup, include=FALSE}
library(reticulate)
```
```{python include=FALSE}
result = 1 + 1
```
1 + 1 = `r py$result` # 1 + 1 = 2
Where py$result means: take the value of the Python variable called result.

How do I escape an RMarkdown chunk?

I am trying to render the syntax for chunks of code in RMarkdown to a pdf. The final output should look like
```{r}
#some code
```
Rather than just
#some code
The best options to answer this can be found on the RStudio website. See the article on getting verbatim R chunks into rmarkdown http://rmarkdown.rstudio.com/articles_verbatim.html
My preferred solution is to add an inline R code at the end of the first line to make the chunk appear correctly in the output like so:
```{r eval=TRUE}` r ''`
seq(1, 10)
```
Which produces
```{r eval=TRUE}
seq(1:10)
```
Rather than
## [1] 1 2 3 4 5 6 7 8 9 10
Another way to do the same thing is treat the code chunk as a string (I don't usually use the -> operator but in this case I think this improves readability):
```{r comment = ""}
"{r eval=TRUE}
seq(1, 10)
" -> my_code_string
cat("```", my_code_string, "```", sep = "")
```
Which outputs:
```{r eval=TRUE}
seq(1, 10)
```
This question is also a possible duplicate of How to embed and escape R Markdown code in a R Markdown document

read table with spaces in one column

I am attempting to extract tables from very large text files (computer logs). Dickoa provided very helpful advice to an earlier question on this topic here: extracting table from text file
I modified his suggestion to fit my specific problem and posted my code at the link above.
Unfortunately I have encountered a complication. One column in the table contains spaces. These spaces are generating an error when I try to run the code at the link above. Is there a way to modify that code, or specifically the read.table function to recognize the second column below as a column?
Here is a dummy table in a dummy log:
> collect.models(, adjust = FALSE)
model npar AICc DeltaAICc weight Deviance
5 AA(~region + state + county + city)BB(~region + state + county + city)CC(~1) 17 11111.11 0.0000000 5.621299e-01 22222.22
4 AA(~region + state + county)BB(~region + state + county)CC(~1) 14 22222.22 0.0000000 5.621299e-01 77777.77
12 AA(~region + state)BB(~region + state)CC(~1) 13 33333.33 0.0000000 5.621299e-01 44444.44
12 AA(~region)BB(~region)CC(~1) 6 44444.44 0.0000000 5.621299e-01 55555.55
>
> # the three lines below count the number of errors in the code above
Here is the R code I am trying to use. This code works if there are no spaces in the second column, the model column:
my.data <- readLines('c:/users/mmiller21/simple R programs/dummy.log')
top <- '> collect.models\\(, adjust = FALSE)'
bottom <- '> # the three lines below count the number of errors in the code above'
my.data <- my.data[grep(top, my.data):grep(bottom, my.data)]
x <- read.table(text=my.data, comment.char = ">")
I believe I must use the variables top and bottom to locate the table in the log because the log is huge, variable and complex. Also, not every table contains the same number of models.
Perhaps a regex expression could be used somehow taking advantage of the AA and the CC(~1) present in every model name, but I do not know how to begin. Thank you for any help and sorry for the follow-up question. I should have used a more realistic example table in my initial question. I have a large number of logs. Otherwise I could just extract and edit the tables by hand. The table itself is an odd object which I have only ever been able to export directly with capture.output, which would probably still leave me with the same problem as above.
EDIT:
All spaces seem to come right before and right after a plus sign. Perhaps that information can be used here to fill the spaces or remove them.
try inserting my.data$model <- gsub(" *\\+ *", "+", my.data$model) before read.table
my.data <- my.data[grep(top, my.data):grep(bottom, my.data)]
my.data$model <- gsub(" *\\+ *", "+", my.data$model)
x <- read.table(text=my.data, comment.char = ">")