2

I have an R-markdown document in a for loop (testing various kinds of models), and I would like to set them off with HTML Headers, as it is otherwise hard to find the models I am looking for. There is the "asis" option, but that turns off formatting for the entire block, which is not what I want. I have tried a few things I found here, but nothing really works. Here is my code:

---
title: "Untitled"
author: "Mike Wise - 25 Jul 2014"
date: "November 2, 2015"
output: html_document
---

Test

```{r, echo=T}
for (i in 1:3){
  print("<h1>Title</h1>")
  #print("##Title")
  m <- data.frame(matrix(runif(25),5,5))
  print(m)
}
```

Here is one try that does not have the right title formatting:

enter image description here

And here is what it looks like with the results="asis" option:

enter image description here

5
  • why not use kable(m, format = "html") and keep the asis? Commented Nov 2, 2015 at 14:00
  • It is okay for tables, and something I considered, but in this application those things printered out are convergence messages for the different algorithms, i.e. not tables, and not the same for each iteration of the for loop. So that is not really an option.\ Commented Nov 2, 2015 at 14:04
  • 1
    if you have convergence messages from model fit results you may want to have a look at broom::tidy to convert your model fit results into data.frames which then again could be displayed with kable. Commented Nov 2, 2015 at 14:39
  • Well, it is a lot of things, really. Convergence messages, summary, confusion matrix, all sorts of things that I might find useful for troubleshooting and/or picking between algorithms.I kind of wanted to keep it simple. But if there is no way to do what I asked, then I suppose I will have to go down that road. Commented Nov 2, 2015 at 16:13
  • if it's not a dataframe output, you could include an example of the outputs you do have. Commented Nov 2, 2015 at 19:02

3 Answers 3

3

Okay, it is a year and a half later and I still needed this from time to time, but I learned enough since then to know how to do it properly. You need to write a knitr "output hook", and modify the output so the html can "escape" through.

The following accomplishes this:

  • Added a knitr output hook.
  • Defined a syntax to specify the needed tag and content
    • for example to get <h1>some_text</h1> use htmlesc<<(h1,some_text)>>
  • Figured out a regexp that extracts the h1 and some_text and reformats it as properly tagged html, removing the ## that knitr inserted as well.
  • Added some more test cases to make sure it did some additional things (like h4, p, proper placement of plots and tables, etc.)
  • Added another regexp to remove double escaped lines which was adding some unwanted whitespace paneled constructs.

So here is the code:

---
title: "Output Hook for HTML Escape"
author: "Someone"
date: "2017 M04 25"
output: 
  html_document:
    keep_md: true
---

```{r setup, include=T,echo=TRUE}
knitr::opts_chunk$set(echo = TRUE)
hook_output <- knitr::knit_hooks$get("output")


knitr::knit_hooks$set(output=function(x,options){
  xn <- hook_output(x,options)
  # interestingly xn is a big character string. 
  # I had expected a list or vector, but the length of x is 1 and the class is character.

  # The following regexp extracts the parameters from a statement of the form
  # htmlesc<<(pat1,pat2)>> and converts it to <pat1>pat2</pat1>
  xn <- gsub("## htmlesc<<([^,]*),{1}([^>>]*)>>","\n```\n<\\1>\\2</\\1>\n```\n",xn)
  # now remove double escaped lines that occur when we do these right after each other
  gsub(">\n```\n\n\n```\n<",">\n<",xn)
}
)
```

## An analysis loop in a single R chunk with R Markdown

In the following, we do a loop and generate 3 sets of data:

(@) We have some explanitory text
(@) then we do a bar plot with ggplot
(@) then we print out a table
(@) then we do a base plot - just for fun

```{r, echo=T, fig.height=3,fig.width=5}
library(knitr)
library(tidyr)
library(ggplot2)
set.seed(123)

for (i in 1:3){
  mdf <- data.frame(matrix(runif(25),5,5))
  cat(sprintf("htmlesc<<h1,Title %d>>\n",i))
  cat(sprintf("htmlesc<<h4,Smaller Title - also for %d>>\n",i))
  cat(sprintf("htmlesc<<p,and some text talking about this %d example>>\n",i))
  print(sapply(mdf,mean))
  gdf <- gather(mdf,series,val)
  gp <- ggplot(gdf)+geom_bar(aes(series,val,fill=series,color=I("black")),stat="identity")
  print(gp)
  print(mdf)
  plot(mdf)
}
```

And this is the output (shrunk a bit as you don't need the details).

enter image description here

The only real docs for this by the way are Yihui's excellent knitr book, a search finds it easily.

Sign up to request clarification or add additional context in comments.

Comments

1

You could try using the kable function:

```{r, echo=T, results="asis"}
library(knitr)
for (i in 1:3){
  print("<h1>Title</h1>")
  #print("##Title")
  m <- data.frame(matrix(runif(25),5,5))
  print(kable(m, format = "html"))
}
```

Which gives me:

enter image description here

1 Comment

See my comment above. It is not really about tables, it is about various kinds of output in the for loop. This is just a toy sample. So Kable is not really the way forward. But thanks for the suggestion.
1

Try this one.

```{r, echo=F, results="asis"}
for (i in 1:3){
  library(knitr)
  print("<h1>Title</h1>")
  #print("##Title")
  m1 <- knitr::kable(data.frame(matrix(runif(25),5,5)))
  print(m1)
}

```

1 Comment

Same as suggested above by jeremycg. Has the same issue. I need it to work for general output, not just kable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.