0

I would like to use a user defined function in Shiny to perform a simple calculation with output two variables. The function I wrote works when it is not part of a shiny app. However when part of a Shiny, the returned object (dfr) is ‘not in scope’. What am I missing?

library(shiny)

# Function ----------------------------------------------------------------
convert <- function(coef_1, coef_2, vec) {
  part_1 <- coef_1/(2*sin((vec/2)*pi/180))
  part_2 <- 2*(180/pi)*(asin(coef_2/(2*part_1)))
  dfr <- data.frame(part_1, part_2)
  return(dfr)
}
# End Function ------------------------------------------------------------


ui <- fluidPage(
   sidebarLayout(
      sidebarPanel(
        textInput("num", h3("Enter number to convert:"), value = NULL)
      ),
      mainPanel(
        verbatimTextOutput("text1", placeholder = TRUE),
        verbatimTextOutput("text2", placeholder = TRUE)
      )
   )
)

server <- function(input, output) {

  nums_str <- as.character(input$num)
  nums_vector <- as.numeric(unlist(strsplit(nums_str, split = ",")))
  convert(1.5, 1.1, nums_vector)

  output$text1 <- renderText({
    req(input$num)
    dfr$part_1
    })

  output$text2 <- renderText({
    req(input$num)
    dfr$part_2
    })

}

shinyApp(ui = ui, server = server)
4
  • 1
    convert(1.5, 1.1, c(5,10)) just prints a dataframe as output. Use dfr <- convert(1.5, 1.1, c(5,10)) instead to store the dataframe in dfr. But I don't understand why you need input$num in this case. Commented Jun 12, 2020 at 18:53
  • This works, thank you! Regarding your question, I made a mistake in the example, the 3rd parameter in the function (c(5, 10)) is a vector supposed to be read from the text box. That is why I check that it is not empty. Commented Jun 12, 2020 at 19:46
  • 1
    Then you'll have to put this in a reactive() expression Commented Jun 12, 2020 at 19:51
  • I have edited the example to show the right intent i.e. using the text box input as the 3rd argument in the function. Commented Jun 12, 2020 at 19:54

1 Answer 1

2

When you use inputs, you need to do it in reactive environment, such as reactive(), renderDataTable(), etc.

Here, you need to run your function in a reactive() and then call it with dfr() in the outputs.

server <- function(input, output) {

  dfr <- reactive({
    convert(1.5, 1.1, as.numeric(input$num))
  })

  output$text1 <- renderText({
    req(input$num)
    dfr()$part_1
  })

  output$text2 <- renderText({
    req(input$num)
    dfr()$part_2
  })

}

Since this is quite basic stuff with R Shiny, checking some tutorials might be very useful.

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.