1

I've built a function in rmarkdown to produce some HTML output with given values, but I want it to work if one of the passed values references a ggplot object.

Basically, knitr renders this perfectly:

x <- [R computation]
y <- [ggplot figure]

<div id="some_number">`r x`</div>
<div id="some_figure">
```{r}
y
```
</div>

But I don't want to have to rewrite that every time I use that particular chunk of html with different x and y. So I wrote the following function:

html_func <- function(x,y) {

    template <- "
<div id=\"some_num\">{x}</div>
<div id=\"some_fig\">{y}</div>
    "

    instance <- glue::glue(template)
    output <- knitr::asis_output(instance)

    return(output)
}

number <- [R computation]
figure <- [ggplot figure]

html_func(number, figure)

The rendered page shows the "number" computed correctly within the div, but doesn't render the plot.

How can I get it to produce the plot within the HTML container?

UPDATE: Commenter suggested using live data so here we go.

This works:

```{r}
library(ggplot2)
data(mtcars)

number <- mean(mtcars$mpg)
figure <- ggplot2::ggplot(mtcars, aes(x=hp, y=mpg)) + 
    geom_point()
```
<div id="some_number">`r number`</div>
<div id="some_figure">
```{r echo=FALSE}
figure
```
</div>

But this does not. The computation outputs fine, but the plot does not render.

```{r}
library(ggplot2)
data(mtcars)

number <- mean(mtcars$mpg)
figure <- ggplot2::ggplot(mtcars, aes(x=hp, y=mpg)) + 
    geom_point()

html_func <- function(x,y) {

    template <- "
<div id=\"some_num\">{x}</div>
<div id=\"some_fig\">{y}</div>
        "

    instance <- glue::glue(template)
    output <- knitr::asis_output(instance)

    return(output)
}

html_func(number, figure)
```

Here's a screenshot comparing the two.

Difference in html rendering

6
  • Hopefully it's clear in the example that the text in [] are just placeholders for arbitrary content, not actual syntax. Commented Nov 4, 2021 at 22:21
  • I can't get your function to work (maybe show some actual objects that allow it to work for you?) but I'm wondering if you need an explicit print() for the plot. That would be necessary in a results = "asis" style chunk, anyway. Commented Nov 4, 2021 at 22:38
  • Thank you @aosmith. I've updated the post to correct a small error that might have caused problems, replicated the issue with data, and shown my outputs. Commented Nov 5, 2021 at 15:14
  • You can get the plot by using print(figure) instead of just figure but it appears you also still get the printed object. Are you attached to knitr::asis_output() or would you consider using a results = "asis" chunk? I've never used one for writing HTML with R output, though, only markdown, so maybe that's a problem. Commented Nov 5, 2021 at 16:11
  • So as you noted, print(figure) produced the plot, but not rendered within the HTML container, and the printed object still appears. I'm not married to knitr::asis_output() but doing {r results="asis"] produces the same thing. Commented Nov 5, 2021 at 16:40

1 Answer 1

0

So this is a BAD solution.

```{r}
html_func_open <- function(x) {

    template <- "
<div id=\"some_num\">{x}</div>
<div id=\"some_fig\">
    "

    instance <- glue::glue(template)
    output <- knitr::asis_output(instance)

    return(output)
}

html_func_close <- function() {
      template <- "
</div>
    "

    instance <- glue::glue(template)
    output <- knitr::asis_output(instance)

    return(output)
}

html_func_open(number)
figure
html_func_close()
```

I get the output I want by doing the plot outside of the HTML template, then closing up the HTML in a second function. This allows the HTML on either side of the figure to be as complex as I want. But it's not really an ideal solution, since It requires multiple lines every time I want to add in a new figure, which limits the complexity with which I can build HTML containers.

So still seeking a better solution where I can just pass the figure to the function and have it render properly.

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

Comments

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.