6

My ggvis plot depends on several input fields that work like filter for input data. For some of combinations the resulting data frame is empty and ggvis throws error and breaks the whole application. I tried to put

if(nrow(inputdataframe) == 0) return NULL 
if(nrow(inputdataframe) == 0) return ggvis()

which didn't help. What is the proper return parameter in this situation (I want to have an empty plot or some text message instead)?

server.R

effvis <- reactive ({
      dta <- siteeff()
      if(nrow(dta)  == 0) return(NULL)
      dta %>%
          ggvis(~param.value, ~yvar) %>%
          layer_points( size := 50, size.hover := 200) %>%
          set_options(width = 800, height = 500)
})
effvis %>% bind_shiny("effplot")

ui.R --

ggvisOutput("effplot")

Update

I don't want to show all data when data is empty (as suggested here) It's confusing

Community
  • 1
  • 1
RInatM
  • 1,208
  • 1
  • 17
  • 39
  • I'm interested in this as well. I just conditionally feed a data.frame with the same columns and zeros. You should be able to use `conditionalPanel` in the ui.R that looks at a reactive string indicating whether the data.frame is empty, but it doesn't always work in my case. – ideamotor Sep 23 '14 at 19:03
  • Your "here" link was helpful to me in the past. I'd also check out the link to the app she got working in the comments. Do you have input controls in your ui? You should test that those exist in server.r – miles2know Sep 25 '14 at 02:01
  • @miles2know thanks for pointing to comments. Indeed, I looked at her code and found validate() function, which I didn't know about - http://shiny.rstudio.com/articles/validation.html But still, it doesn't seem to work for ggvis – RInatM Sep 25 '14 at 08:24

2 Answers2

4

So it would have been helpful to see some more of the logic in your code. I guess I'd say in general it's really important to understand how reactive expressions work in the context of program logic. I'd try reading as much code on the shiny home page as you can. Here is a quick script I wrote up that I think gets at what you are asking. cheers.

Global.r

    library(plyr)
    library(dplyr)

    exp <- data.frame(Ind=rep(c("a","b"),each=50),val1=rgamma(100,10,5),val2=rnorm(100,2,3.5))

Server.r

    library(shiny)
    library(ggvis)

    shinyServer(function(input, output, session) {

    output$selectO <- renderUI({ selectInput(inputId="selectI", label = h4("Level to Plot"), 
        choices = list("a","b","c"),selected="a")
    })

    observe({

    if(!is.null(input$selectI)){ 

    expfilter <- reactive({
             vals <- exp %>% filter(Ind == input$selectI)
             return(vals)
    })

    if(nrow(expfilter())==0){

    fail <- reactive({ return("filter failed") })

    output$trouble <- renderText({fail()}) # notice the use of () since fail is a function. when you want to grab the values of reactives use the ()

    } else {

    success <- reactive({ return("good") })

    output$trouble <- renderText({success()})   

    P1 <- reactive({ 
        expfilter %>% ggvis(~val1, ~val2) %>% 
        add_axis("x",title="Var1",title_offset=45,properties=axis_props(labels=list(fontSize = 13, fontWeight = "bold"),title=list(fontSize = 15))) %>% 
        add_axis("y",properties=axis_props(labels=list(fontSize = 13, fontWeight = "bold")))
    })  

    P1 %>% bind_shiny("plot1")

       }
      }
     })
    })


ui.r

    library(shiny)

    shinyUI(fluidPage(
     column(3,
      wellPanel(
       uiOutput("selectO")
       )
      ),
     column(9,
      wellPanel(
       ggvisOutput("plot1")),
        wellPanel(h6("How Did the Filter Do"),
        textOutput("trouble")
       )
      )
     )
    )  
miles2know
  • 737
  • 8
  • 17
  • thanks for this snippet, it hellped me to realize, that it's not ggviz by itself, but only %>%layer_smooths() is responsible for breaking the code If you add %>% layer_smooths() to your graph, your workaround doesn't work and application breaks. I submitted an issue, but the question stays - how not to launch ggvis when data is empty – RInatM Sep 26 '14 at 08:03
  • Hi. That doesn't surprise me. I wasn't trouble shooting your ggvis code I just threw in any old code I had lying around that worked. It looked to me like you are trying to use shiny and figure out how to not have it break when your filters come up empty. That was what I was getting at. So unless I'm misunderstanding you the above code provides a way forward on that front. Again though my example above was not meant to demonstrate anything particular to ggvis per se. best of luck. – miles2know Sep 26 '14 at 11:23
  • The `observe()` function was the missing piece for me. Cheers. – c.gutierrez Jan 20 '15 at 04:15
  • Nice solution. The only problem is that you lose the ggvis "smooth transition" where only the points move, and the plot doesn't have to be redrawn. Any ideas @hadley? – Juancentro Apr 24 '15 at 23:11
  • In my case, with the latest shiny, I can just send an empty data.table (or data.frame) and shiny just plots an empty graph (the data.frame or data.table has to have the corresponding columns) – Juancentro Apr 24 '15 at 23:31
  • @Juancentro yes, it's fixed in new release, if you post this as an answer, I will accept it – RInatM May 19 '15 at 15:04
3

In my case, with the latest shiny, I can just send an empty data.table (or data.frame) and shiny just plots an empty graph (the data.frame or data.table has to have the corresponding columns)

Juancentro
  • 1,119
  • 7
  • 19
  • Have you got it working with remote `dplyr` tables too? I cannot reproduce the example cause don't know of any public db I could use, but I get the following error when the tbl is not local `Error in UseMethod("prop_type") : no applicable method for 'prop_type' applied to an object of class "c('tbl_mysql', 'tbl_sql', 'tbl_lazy', 'tbl')"` – Dambo Aug 05 '16 at 21:11
  • thanks for the answer this is what I did to resolve a similar situation in my application but I would like to add that you have to return a ggvis object not data.frame. maybe that what you meant but I had to struggle a little more to get that, so instead on retuning `NULL` you have to return an empty data.frame with the same columns and then use dplyr to create ggvis `data.frame(col1='',col2='') %>% ggvis(~col1,~col2) %>%layer_points()` + for the answer :) – rahul Aug 10 '17 at 07:46