2
votes

I'm exploring the possibilities with interactive ggplot2 in shiny. Inspired by this I created a shiny app that exclude points from a dataset and plots the data where the excluded points are of a different color.

app.R

library(shiny)
library(ggplot2)
server<-function(input, output) {
  data <- reactive({
    set.seed(10)
    df=data.frame(x=rnorm(100),y=rnorm(100))
    df
  })

  vals<-reactiveValues(keeprows=rep(TRUE, 100))

  output$plot1 <- renderPlot({
    df=data()
    keep=df[vals$keeprows, ,drop=FALSE]
    exclude=df[!vals$keeprows, ,drop=FALSE]
    plot=ggplot(data=keep,aes(x,y))+geom_point()+theme_bw()+
      geom_point(data=exclude,fill=NA,col="black",alpha=0.75,shape=21)
    plot
  })

  observeEvent(input$plot1_click,{
    df=data()
    res <- nearPoints(df, input$plot1_click, allRows = TRUE,threshold=5)
    vals$keeprows <- xor(vals$keeprows, res$selected_)

  })

}

ui <- fluidPage(

  titlePanel("Reactive test"),


  mainPanel(
    plotOutput("plot1",click="plot1_click")
  )
)

shinyApp(ui = ui, server = server)

This works perfectly, but now I want to be able to define vals with:

vals<-reactiveValues(keeprows=rep(TRUE,nrow(CustomDataInput))

In the case of my example, I tried accessing number of rows from the data created in data():

vals<-reactiveValues(keeprows=rep(TRUE,nrow(data()))

This gives me an error because I tried to access a reactive variable in a non-reactive environment. Is there a way to access the data created in a reactive function to define reactiveValues?

Thank you for your time!

1

1 Answers

4
votes

The error pretty much addresses the problem. The correct way to do this is as follows.

library(shiny)
library(ggplot2)
server<-function(input, output) {

  vals <- reactiveValues()
  data <- reactive({
    set.seed(10)
    df=data.frame(x=rnorm(100),y=rnorm(100))
    vals$keeprows = rep(TRUE,nrow(df))
    df
  })

  #vals<-reactiveValues(keeprows=rep(TRUE,100))
  output$plot1 <- renderPlot({
    df=data()
    keep=df[vals$keeprows, ,drop=FALSE]
    exclude=df[!vals$keeprows, ,drop=FALSE]
    plot=ggplot(data=keep,aes(x,y))+geom_point()+theme_bw()+
      geom_point(data=exclude,fill=NA,col="black",alpha=0.75,shape=21)
    plot
  })

  observeEvent(input$plot1_click,{
    df=data()
    res <- nearPoints(df, input$plot1_click, allRows = TRUE,threshold=5)
    vals$keeprows <- xor(vals$keeprows, res$selected_)

  })

}

ui <- fluidPage(

  titlePanel("Reactive test"),


  mainPanel(
    plotOutput("plot1",click="plot1_click")

  )
)

shinyApp(ui = ui, server = server)

Declare the vals variable before hand and use that in reactive() function to send variables to vals as shown above. You should be fine.