6

The following content of a .Rmd file:

---
title: "Untitled"
output:
  html_document: default
---

```{r cars}
mtcars$am <- sprintf("(%s)", as.character(mtcars$am))
knitr::kable(mtcars, format = "html")
```

Will show ordered lists <ol><li></li></ol> in the am column, instead of the numbers in brackets (as produced with the sprintf) after rendering to html.

Is this intended? How can I work around this and have numbers in brackets show as they are in the html output?

The output of knitr::kable seems to be fine, showing:

<td style="text-align:left;"> (1) </td>

Details:

  • Using knitr 1.20
  • RStudio Server 1.1.453
  • note that removing format = "html" does not resolve the issue as in the real-life context I would like to do advanced formatting with css e.g. based on the classes of the produced tables

A quick workaround solution based on Michael Harper's accepted answer may be a method like so:

replacechars <- function(x) UseMethod("replacechars")
replacechars.default <- function(x) x
replacechars.character <- function(x) {
  x <- gsub("(", "&lpar;", x, fixed = TRUE)
  x <- gsub(")", "&rpar;", x, fixed = TRUE)
  x
}
replacechars.factor <- function(x) {
  levels(x) <- replacechars(levels(x))
  x
}
replacechars.data.frame <- function(x) {
  dfnames <- names(x)
  x <- data.frame(lapply(x, replacechars), stringsAsFactors = FALSE)
  names(x) <- dfnames
  x
}

Example use:

mtcars <- datasets::mtcars

# Create a character with issues
mtcars$am <- sprintf("(%s)", as.character(mtcars$am))

# Create a factor with issues
mtcars$hp <- as.factor(mtcars$hp)
levels(mtcars$hp) <- sprintf("(%s)", levels(mtcars$hp))

replacechars(mtcars)
Jozef
  • 2,617
  • 14
  • 19
  • 1
    @zack this is true, `knitr::kable` will then automatically select the format to produce - in this case it will create a markdown table, which gets rendered as expected. This however does not resolve my issue, as I need the html format (to be able to format the output further with css, etc.) – Jozef Dec 04 '18 at 17:18

2 Answers2

4

If you don't want to remove the format="html" argument, you could try using the HTML character entities for the parentheses (&lpar and &rpar) and then add the argument escape = FALSE:

```{r cars}
mtcars$am <- sprintf("&lpar;%s&rpar;", as.character(mtcars$am))
knitr::kable(mtcars, format = "html", escape = FALSE)
```

enter image description here

Still not entirely sure of what is causing the error though. It seems that the specific combination of parentheses is being processed strangely by knitr.

Michael Harper
  • 14,721
  • 2
  • 60
  • 84
  • 1
    Thank you, that fixed my issue, accepting your answer. I also raised and issue on knitr's github - https://github.com/yihui/knitr/issues/1641. – Jozef Dec 06 '18 at 08:44
3

An alternative solution is to escape the parentheses, e.g.,

mtcars$am <- sprintf("\\(%s)", as.character(mtcars$am))

Then you won't need escape = FALSE.

See https://pandoc.org/MANUAL.html#backslash-escapes in Pandoc's Manual.

Yihui Xie
  • 28,913
  • 23
  • 193
  • 419