Let's learn shiny together (5) - Reaction formula

What is shiny? Shiny is an R package that allows you to easily build interactive web applications (apps) directly from R. This series is a long tutorial, taking you to learn shiny from simple to deep.
insert image description here
In the previous section, we introduced how to output controls in shiny in the article "R Language Series Tutorial—Let's learn shiny together (4)". Today we will introduce the reactive formula.
Let's first look at the picture below.
insert image description here
After entering the name, you can get Hello zero-based scientific research! See the following code for specific settings. In textInput, we define the variable "name", which means that we input the words "zero-based, scientific research, scientific research" and then use "name" to define it, and then define an output variable at the front end. "greeting". The next step is to process the data at the backend. renderText reads the variable input$name, and then integrates it into Hello Zero-Basic Science Research! through the paste0 function, and then defines it in output $greeting.

library(shiny)
## Warning: 程辑包'shiny'是用R版本4.2.2 来建造的
ui <- fluidPage(
  textInput("name", "What's your name?"),
  textOutput("greeting")
)

server <- function(input, output, session) {
    
    
  output$greeting <- renderText({
    
    
    paste0("Hello ", input$name, "!")
  })
}

shinyApp(ui, server)
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.

insert image description here
Let's talk about the reaction formula, what is the reaction formula? It can be regarded as a tool or bridge connecting the front and back. Let’s take a look at the following code. The function implemented is exactly the same as before, but this time "greeting" and output $ greeting are not directly connected. There is an extra string in the middle, and the string replaces "greeting" Associated with output$greeting.

ui <- fluidPage(
  textInput("name", "What's your name?"),
  textOutput("greeting")
)

server <- function(input, output, session) {
    
    
  output$greeting <- renderText(string())
  string <- reactive(paste0("Hello ", input$name, "!"))
}

shinyApp(ui, server)

insert image description here
Looking at it with a mind map,
insert image description here
it is also possible to change the order, but I think it is better not to write like this

ui <- fluidPage(
  textInput("name", "What's your name?"),
  textOutput("greeting")
)

server <- function(input, output, session) {
    
    
  output$greeting <- renderText(string())
  string <- reactive(paste0("Hello ", input$name, "!"))
}

shinyApp(ui, server)

insert image description here
Let's look at an example, column creates a column of objects, width is the width it wants to set, the range is 1-12, "Distribution 1", each column has 3 buttons, "Distribution 2" is the same, and finally come out.

ui <- fluidPage(
  fluidRow(
    column(4, 
      "Distribution 1",
      numericInput("n1", label = "n", value = 1000, min = 1),
      numericInput("mean1", label = "µ", value = 0, step = 0.1),
      numericInput("sd1", label = "σ", value = 0.5, min = 0.1, step = 0.1)
    ),
    column(4, 
      "Distribution 2",
      numericInput("n2", label = "n", value = 1000, min = 1),
      numericInput("mean2", label = "µ", value = 0, step = 0.1),
      numericInput("sd2", label = "σ", value = 0.5, min = 0.1, step = 0.1)
    ),
    column(4,
      "Frequency polygon",
      numericInput("binwidth", label = "Bin width", value = 0.1, step = 0.1),
      sliderInput("range", label = "range", value = c(-3, 3), min = -5, max = 5)
    )
  ),
  fluidRow(
    column(9, plotOutput("hist")),
    column(3, verbatimTextOutput("ttest"))
  )
)

server <- function(input, output, session) {
    
    
  output$hist <- renderPlot({
    
    
    x1 <- rnorm(input$n1, input$mean1, input$sd1)
    x2 <- rnorm(input$n2, input$mean2, input$sd2)
    
    freqpoly(x1, x2, binwidth = input$binwidth, xlim = input$range)
  }, res = 96)

  output$ttest <- renderText({
    
    
    x1 <- rnorm(input$n1, input$mean1, input$sd1)
    x2 <- rnorm(input$n2, input$mean2, input$sd2)
    
    t_test(x1, x2)
  })
}

shinyApp(ui, server)

insert image description here
We can see that the above example is more complicated, and the relationship is also very confusing. We can rewrite it using reactive. In the server part, x1 and x2 are generated reactively. Call reactive() and assign the result to a variable.

ui <- fluidPage(
  fluidRow(
    column(4, 
      "Distribution 1",
      numericInput("n1", label = "n", value = 1000, min = 1),
      numericInput("mean1", label = "µ", value = 0, step = 0.1),
      numericInput("sd1", label = "σ", value = 0.5, min = 0.1, step = 0.1)
    ),
    column(4, 
      "Distribution 2",
      numericInput("n2", label = "n", value = 1000, min = 1),
      numericInput("mean2", label = "µ", value = 0, step = 0.1),
      numericInput("sd2", label = "σ", value = 0.5, min = 0.1, step = 0.1)
    ),
    column(4,
      "Frequency polygon",
      numericInput("binwidth", label = "Bin width", value = 0.1, step = 0.1),
      sliderInput("range", label = "range", value = c(-3, 3), min = -5, max = 5)
    )
  ),
  fluidRow(
    column(9, plotOutput("hist")),
    column(3, verbatimTextOutput("ttest"))
  )
)


server <- function(input, output, session) {
    
    
  x1 <- reactive(rnorm(input$n1, input$mean1, input$sd1))
  x2 <- reactive(rnorm(input$n2, input$mean2, input$sd2))

  output$hist <- renderPlot({
    
    
    freqpoly(x1(), x2(), binwidth = input$binwidth, xlim = input$range)
  }, res = 96)

  output$ttest <- renderText({
    
    
    t_test(x1(), x2())
  })
}

shinyApp(ui, server)

insert image description here
The following diagram shows the relationship, and the revised one is easier to understand.
insert image description here
Let's simplify the above modules

ui <- fluidPage(
  fluidRow(
    column(3, 
      numericInput("lambda1", label = "lambda1", value = 3),
      numericInput("lambda2", label = "lambda2", value = 5),
      numericInput("n", label = "n", value = 1e4, min = 0)
    ),
    column(9, plotOutput("hist"))
  )
)
server <- function(input, output, session) {
    
    
  x1 <- reactive(rpois(input$n, input$lambda1))
  x2 <- reactive(rpois(input$n, input$lambda2))
  output$hist <- renderPlot({
    
    
    freqpoly(x1(), x2(), binwidth = 1, xlim = c(0, 40))
  }, res = 96)
}

shinyApp(ui, server)

insert image description here
Add a timer reaction formula, and get a moving picture, and my webpage here will not move when it is displayed

ui <- fluidPage(
  fluidRow(
    column(3, 
      numericInput("lambda1", label = "lambda1", value = 3),
      numericInput("lambda2", label = "lambda2", value = 5),
      numericInput("n", label = "n", value = 1e4, min = 0)
    ),
    column(9, plotOutput("hist"))
  )
)

server <- function(input, output, session) {
    
    
  timer <- reactiveTimer(500)
  
  x1 <- reactive({
    
    
    timer()
    rpois(input$n, input$lambda1)
  })
  x2 <- reactive({
    
    
    timer()
    rpois(input$n, input$lambda2)
  })
  
  output$hist <- renderPlot({
    
    
    freqpoly(x1(), x2(), binwidth = 1, xlim = c(0, 40))
  }, res = 96)
}

shinyApp(ui, server)

insert image description here
Add click button actionButton, you can draw according to click button

ui <- fluidPage(
  fluidRow(
    column(3, 
      numericInput("lambda1", label = "lambda1", value = 3),
      numericInput("lambda2", label = "lambda2", value = 5),
      numericInput("n", label = "n", value = 1e4, min = 0),
      actionButton("simulate", "Simulate!")
    ),
    column(9, plotOutput("hist"))
  )
)

server <- function(input, output, session) {
    
    
  x1 <- reactive({
    
    
    input$simulate
    rpois(input$n, input$lambda1)
  })
  x2 <- reactive({
    
    
    input$simulate
    rpois(input$n, input$lambda2)
  })
  output$hist <- renderPlot({
    
    
    freqpoly(x1(), x2(), binwidth = 1, xlim = c(0, 40))
  }, res = 96)
}

shinyApp(ui, server)

insert image description here
Use the eventReactive function instead of reactive, which has the effect of triggering time, and there is no picture when it is not triggered

ui <- fluidPage(
  fluidRow(
    column(3, 
           numericInput("lambda1", label = "lambda1", value = 3),
           numericInput("lambda2", label = "lambda2", value = 5),
           numericInput("n", label = "n", value = 1e4, min = 0),
           actionButton("simulate", "Simulate!")
    ),
    column(9, plotOutput("hist"))
  )
)

server <- function(input, output, session) {
    
    
  x1 <- eventReactive(input$simulate, {
    
    
    rpois(input$n, input$lambda1)
  })
  x2 <- eventReactive(input$simulate, {
    
    
    rpois(input$n, input$lambda2)
  })
  
  output$hist <- renderPlot({
    
    
    freqpoly(x1(), x2(), binwidth = 1, xlim = c(0, 40))
  }, res = 96)
}

shinyApp(ui, server)

insert image description here

Guess you like

Origin blog.csdn.net/dege857/article/details/132607515