简体   繁体   English

传递一个 reactiveEvent 来更新 Shiny 中的 plot 回归

[英]Passing a reactiveEvent to update plot regression in Shiny

I have the following App:我有以下应用程序:

在此处输入图像描述

The objective is to:目标是:

    1. Add new points to the plot when the user clicks on it.当用户点击它时,将新点添加到 plot。
    1. These are updated in the table (where you can remove points also)这些在表中更新(您也可以在其中删除点)
    1. (Where the App fails): Plot the linear regression and spline regression based on the new users updated data. (应用程序失败的地方):Plot 基于新用户更新数据的线性回归和样条回归。

When I comment-out the lines当我注释掉这些行时

  #geom_line(aes(x=x, y=fitlm(), color="Simple")) +
  #geom_line(aes(x=x, y=fitbslm(), color="B-spline")) +

in the ggplot renderPlot() function at the end, I am able to add points and update the plot without problem在最后的ggplot renderPlot() function 中,我可以毫无问题地添加点并更新 plot

The problem occurs when I try to add these two lines back into the plot and then the updated data is passed to the fitlm and fitBslm eventReactive() functions.当我尝试将这两行添加回 plot 然后将更新的数据传递给fitlmfitBslm eventReactive()函数时,就会出现问题。

For some reason it doesn't want to re-compute the regressions and apply/update the plot.出于某种原因,它不想重新计算回归并应用/更新 plot。

Question:问题:

How can I introduce the regressions to the ggplot based on the new users updated data.我如何根据新用户更新的数据将回归引入 ggplot。 (I am happy with it updating automatically or through a button) (我很高兴它自动更新或通过按钮更新)

After clicking the Generate Plot button it makes the below plot. However, the plot failed Error: [object Object] when I click on the plot to add a new point.单击Generate Plot按钮后,它会生成以下 plot。但是,当我单击 plot 添加新点时,plot 失败Error: [object Object]

App:应用程序:

library(shiny)
library(dplyr)
library(splines2)
library(ggplot2)


# Get the Temp values, which defines the accepted range of knots
# for the b-spline model.
library(dplyr)
data("airquality")
airquality <- filter(airquality, !is.na(Ozone)) %>% 
  select(c(Ozone, Temp)) %>% 
  set_names(c("x", "y"))
uniqueTemps <- unique(airquality[order(airquality$x), "x"])
selectedTemps <- sample(uniqueTemps, 2)

# Define UI for application that draws a histogram
ui <- shinyUI(fluidPage(
  
  # Application title
  titlePanel("Simple Linear vs Spline Fit"),
  
  # Sidebar
  sidebarLayout(
    sidebarPanel(
      selectInput("knotSel", "Select knot values for B-spline fit:",
                  uniqueTemps, selected=selectedTemps,
                  multiple=TRUE),
      actionButton("calcFit", "Generate Plot"),
      actionButton("computeRegressions", "Compute Regressions")
    ),
    
    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("plot_splines", click = "plot_click"),
      h4("Example Data: airquality {datasets}"),
      p("This plot uses linear models to predict ozone levels based on temperature readings.",
        tags$br(),
        tags$em("Simple formula: ")
        # tags$code("lm(Ozone ~ Temp + I(Temp^2) + I(Temp^3) - 1, airquality)"),
        # tags$br(),
        # tags$em("Spline formula: "),
        # tags$code("lm(airquality$Ozone ~ bSpline(airquality$Temp, knots=getKnots(), degree=3) - 1)")
      ),
      fluidRow(column(width = 6,
                      h4("Click plot to add points"),
                      actionButton("rem_point", "Remove Last Point")
                      #plotOutput("plot1", click = "plot_click")
                      ),
               column(width = 6,
                      h4("Table of points on plot"),
                      tableOutput("table"))),
      fluidRow(column(width = 6,
                      DTOutput('tab1')),
               column(width = 6,
                      DTOutput('tab2'))
               )
    )
  )))

server <- (function(input, output) {
  
  # Load the airquality dataset.
  # data("airquality")
  # # Remove observations lacking an Ozone measure.
  # airquality <- filter(airquality, !is.na(Ozone)) %>% 
  #   select(c(Ozone, Temp)) %>% 
  #   set_names(c("y", "x"))

  
  ########################### Add selections to plot ###########################
  ## 1. set up reactive dataframe ##
  values <- reactiveValues()
  values$DT <- data.frame(x = numeric(),
                          y = numeric()
  ) %>% 
    bind_rows(airquality)
  
  
  
  ## 2. Create a plot ##
  # output$plot1 = renderPlot({
  #   ggplot(values$DT, aes(x = x, y = y)) +
  #     geom_point(size = 5) +
  #     lims(x = c(0, 100), y = c(0, 100)) +
  #     theme(legend.position = "bottom")
  #   # include so that colors don't change as more color/shape chosen
  #   # scale_color_discrete(drop = FALSE) +
  #   # scale_shape_discrete(drop = FALSE)
  # })
  
  ## 3. add new row to reactive dataframe upon clicking plot ##
  observeEvent(input$plot_click, {
    # each input is a factor so levels are consistent for plotting characteristics
    add_row <- data.frame(x = input$plot_click$x,
                          y = input$plot_click$y
    )
    # add row to the data.frame
    values$DT <- rbind(values$DT, add_row)
  })
  
  ## 4. remove row on actionButton click ##
  observeEvent(input$rem_point, {
    rem_row <- values$DT[-nrow(values$DT), ]
    values$DT <- rem_row
  })
  
  ## 5. render a table of the growing dataframe ##
  output$table <- renderTable({
    values$DT
  })
  ##############################################################################
  # Fit the simple linear model
  fitlm <- eventReactive(input$calcFit, {
    slm <- lm(y ~ x + I(x^2) + I(x^3) - 1, values$DT)
    fitlm <- slm$fitted.values
    fitlm
  })
  
  # Get knot selection
  getKnots <- reactive({as.integer(input$knotSel)})
  
  # Fit the spline model, with the knot selection
  fitBslm <- eventReactive(input$calcFit, {
    bsMat <- bSpline(values$DT$x, knots=getKnots(), degree=3)
    bslm <- lm(values$DT$y ~ bsMat - 1)
    bslm
  })
  
  # observeEvent({
  #   print(fitBslm())
  # })
  
  # Generate the plot
  output$plot_splines <- renderPlot({
    splineMdl <- fitBslm()
    fitbslm <- splineMdl$fitted.values
    
    cols <- c("Simple"="#ef615c", "B-spline"="#20b2aa", "knot"="black")
    g <- ggplot(values$DT, aes(x=x, y=y)) +
      geom_point(color="blue") +
     geom_line(aes(x=x, y=fitlm(), color="Simple")) +
      #geom_line(aes(x=x, y=fitbslm(), color="B-spline")) +
      geom_vline(aes(color="knot"), xintercept=getKnots(), linetype="dashed", size=1) +
      scale_colour_manual(name="Fit Lines",values=cols) +
      ggtitle("Ozone as predicted by Temp", "(knots shown as vertical lines)")
    g
  })
  
  output$tab1 <- renderDataTable(
    airquality
  )
  
  output$tab2 <- renderDataTable(
    values$DT
  )
  
})

shinyApp(ui, server)

Change eventReactive to just reactive . eventReactive更改为只是reactive Also, you just need fitbslm in the second geom_line without () .此外,您只需要fitbslm在第二个geom_line中没有() Try this尝试这个

server <- (function(input, output) {

  ########################### Add selections to plot ###########################
  ## 1. set up reactive dataframe ##
  values <- reactiveValues()
  values$DT <- data.frame(x = numeric(),
                          y = numeric()
  ) %>% 
    bind_rows(airquality)
 
  ## 3. add new row to reactive dataframe upon clicking plot ##
  observeEvent(input$plot_click, {
    # each input is a factor so levels are consistent for plotting characteristics
    add_row <- data.frame(x = input$plot_click$x,
                          y = input$plot_click$y
    )
    # add row to the data.frame
    values$DT <- rbind(values$DT, add_row)
  })
  
  ## 4. remove row on actionButton click ##
  observeEvent(input$rem_point, {
    rem_row <- values$DT[-nrow(values$DT), ]
    values$DT <- rem_row
  })
  
  ## 5. render a table of the growing dataframe ##
  output$table <- renderTable({
    values$DT
  })
  ##############################################################################
  # Fit the simple linear model
  # fitlm <- eventReactive(input$calcFit, {
  fitlm <- reactive({
    slm <- lm(y ~ x + I(x^2) + I(x^3) - 1, values$DT)
    fitlm <- slm$fitted.values
    fitlm
  })
  
  # Get knot selection
  getKnots <- reactive({as.integer(input$knotSel)})
  
  # Fit the spline model, with the knot selection
  #fitBslm <- eventReactive(input$calcFit, {
  fitBslm <- reactive({
    bsMat <- bSpline(values$DT$x, knots=getKnots(), degree=3)
    bslm <- lm(values$DT$y ~ bsMat - 1)
    bslm
  })
 
  
  myPlot <- reactive({
    splineMdl <- fitBslm()
    fitbslm <- splineMdl$fitted.values
    cols <- c("Simple"="#ef615c", "B-spline"="#20b2aa", "knot"="black")
    
    g <- ggplot(values$DT, aes(x=x, y=y)) +
      geom_point(color="blue") +
      geom_line(aes(x=x, y=fitlm(), color="Simple")) +
      geom_line(aes(x=x, y=fitbslm , color="B-spline")) +
      geom_vline(aes(color="knot"), xintercept=getKnots(), linetype="dashed", size=1) +
      scale_colour_manual(name="Fit Lines",values=cols) +
      ggtitle("Ozone as predicted by Temp", "(knots shown as vertical lines)")
    g
  })
  
  # Generate the plot
  output$plot_splines <- renderPlot({
    myPlot()
  })
  
  output$tab1 <- renderDataTable(
    airquality
  )
  
  output$tab2 <- renderDataTable(
    values$DT
  )
  
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM