0

I want to create an interactive plot in R Shiny.

Based on some inputs a reactive data frame is created and visualised in a simple scatter plot. Now I want to allow users to select observations in the plot (by clicking the respective points). Everytime a point in the plot is clicked I want to update the column named "selected" in the data frame.

I tried the following code:

library(shiny)
library(ggplot2)
library(tidyverse)

ui <- fluidPage(
  # Input
  numericInput("N", label = "Number of participants", min = 1, max = 10, value = 10),
  # Outputs
  plotOutput(outputId="plot", click = "plot_click"),
  textOutput(outputId = "info"),
  tableOutput(outputId ="tab")  
)

server <- function(input, output, session) {
  # create data frame with random age for the selected number of persons
  data <- reactive({
    tibble(ID = 1:input$N, age = sample(1:100,input$N), selected = "no")
  })

 data <- reactive({
    data() %>% mutate(selected = 
if_else(ID == round(input$plot_click$x) & age == round(input$plot_click$y),"yes",selected))
  })
  
  output$tab <- renderTable({
    data()
  })
  
  output$plot <- renderPlot({
    ggplot(data(), aes(x = ID, y = age, color = selected)) + geom_point(size = 5)
  })
  
  output$info <- renderText({
    if(is.numeric(input$plot_click$x)){
      print(paste("x =",round(input$plot_click$x), "y =", round(input$plot_click$y)))
    }
  })
}

shinyApp(ui = ui, server = server)

However, with this code I get an error message:

Error in : evaluation nested too deeply: infinite recursion / options(expressions=)?

I also tried to create a new data frame instead of updating the old one with the following slightly adjusted code:

library(shiny)
library(ggplot2)
library(tidyverse)

ui <- fluidPage(
  numericInput("N", label = "Number of participants", min = 1, max = 10, value = 10),
  
  plotOutput(outputId="plot", click = "plot_click"),
  textOutput(outputId = "info"),
  tableOutput(outputId ="tab"),
  tableOutput(outputId ="tab2")
  
)

server <- function(input, output, session) {
  # create data frame with random age for the selected number of persons
  data <- reactive({
    tibble(ID = 1:input$N, age = sample(1:100,input$N), selected = "no")
  })
  
  data2 <- eventReactive(input$plot_click,{
    data() %>% mutate(selected = if_else(ID == round(input$plot_click$x) & age == round(input$plot_click$y),"yes",selected))
  })

  output$tab <- renderTable({
    data()
  })
  
  output$tab2 <- renderTable({
    data2()
  })
  
  output$plot <- renderPlot({
    ggplot(data(), aes(x = ID, y = age, color = selected)) + geom_point(size = 5)
  })
  
  output$info <- renderText({
    if(is.numeric(input$plot_click$x)){
      print(paste("x =",round(input$plot_click$x), "y =", round(input$plot_click$y)))
    }
  })
}

shinyApp(ui = ui, server = server)


I don't get an error message in this case and after clicking a point in the plot "data2" is created. However, the table of data2 is only visible for a very short moment and then disappears again.

I just started to work with R Shiny and still struggle a bit to understand the logic behind its reactivity. So I'll appreciate it a lot if someone could give me a hint here.

Thanks

Susanne
  • 1
  • 1
  • I get `C stack usage 15928128 is too close to the limit` and `argument is of length zero` when I try to run your code. No plot is generated. Make sure your example is repoducible. – Claudio Paladini Jun 20 '22 at 12:49
  • Have a look at this: https://stackoverflow.com/questions/50765687/return-datapoints-selected-in-a-plotly-scatterplot – Claudio Paladini Jun 20 '22 at 12:57

0 Answers0