# writing render*() and *Output() functions for UI output

I am the author of the equatiomatic R package. I would like to write and export renderEq() and eqOutput() functions to make it easier to use with Shiny. Unfortunately, I can't figure it out. The below works for a basic shiny app.

library(shiny)
library(shinyWidgets)
library(ggplot2)
library(equatiomatic)
library(gtsummary)
library(gt)

ui <- fluidPage(
titlePanel("equatiomatic w/Shiny"),
sidebarLayout(
sidebarPanel(
multiInput(
inputId = "xvars", label = "Select predictor variables :",
choices = names(mpg)[-8],
selected = "displ"
)
),

mainPanel(
uiOutput("eq"),
gt_output("tbl")
)
)
)

server <- function(input, output) {

model <- reactive({
form <- paste("hwy ~ ", paste(input$xvars, collapse = " + ")) lm(as.formula(form), mpg) }) output$eq <- renderUI(
withMathJax(
helpText(
equatiomatic:::format.equation(
extract_eq(model(), wrap = TRUE, terms_per_line = 3)
)
)
)
)

output$tbl <- render_gt({ as_gt(tbl_regression(model())) }) } shinyApp(ui = ui, server = server)  I'd really like to simplify this so the Ui part is just eqOutput("eq") and the server part is something like output$eq <- renderEq(
extract_eq(model(), wrap = TRUE, terms_per_line = 3)
)


I know of htmlwidgets::shinyWidgetOutput() but that doesn't seem to help in this case because I'm trying to modify a UI element.

Any help would be greatly appreciated.

3 Likes

Cross-posted here.

I think this is a great question, as there seems to be a lack of educational content / tutorials in this area.
From what I gather ' Shiny - Implement render functions — createRenderFunction (rstudio.com)' seems to be a key element.

2 Likes

Thanks @nirgrahamuk! I wasn’t aware of that function so I’ll play around with it some and see if I can get anything to work.

Hi,

If you look at render_gt from gt, or renderText, and renderTable from shiny you can see a general pattern with
installExprFunction to install expr as a function in the env and then
createRenderFunction to process the value

In your example, everything is already processed thanks to withMathJax(helpText(equatiomatic:::format.equation(x)))

So if you use dedicated functions installExprFunction and createRenderFunction and combine it with the transform you use you can create your own rendering function,

library(shiny)
library(shinyWidgets)
library(ggplot2)
library(equatiomatic)
library(gtsummary)
library(gt)

renderEq <- function(expr, env = parent.frame(), quoted = FALSE, outputArgs = list()) {
shiny::installExprFunction(expr = expr, name = "func", eval.env = env, quoted = quoted)
shiny::createRenderFunction(func = func, function(value, session, name, ...) {
as.character(withMathJax(helpText(equatiomatic:::format.equation(x = value))))
}, eqOutput, outputArgs)
}

eqOutput <- function(outputId) {
shiny::htmlOutput(outputId = outputId)
}

ui <- fluidPage(
titlePanel("equatiomatic w/Shiny"),
sidebarLayout(
sidebarPanel(
multiInput(
inputId = "xvars", label = "Select predictor variables :",
choices = names(mpg)[-8],
selected = "displ"
)
),
mainPanel(
eqOutput("eq_new"),
uiOutput("eq"),
gt_output("tbl")
)
)
)

server <- function(input, output) {
model <- reactive({
form <- paste("hwy ~ ", paste(input$xvars, collapse = " + ")) lm(as.formula(form), mpg) }) output$eq_new <- renderEq(expr = extract_eq(model(), wrap = TRUE, terms_per_line = 3))
output$eq <- renderUI( withMathJax( helpText( equatiomatic:::format.equation( extract_eq(model(), wrap = TRUE, terms_per_line = 3) ) ) ) ) output$tbl <- render_gt({
as_gt(tbl_regression(model()))
})

}

shinyApp(ui = ui, server = server)


However, it still remains kind of a glitch where the equation is displayed but not correctly formatted ....

1 Like

Thank you so much! Do you mind elaborating on the equation not be being formatted correctly? At least on my end it looks perfect! I'm on a mac and tested it on safari, chrome, and brave (a bit redundant with chrome but... ).

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.