4

I am trying to use Shiny and ggvis to:

1) upload a data set

2) have the user select 2 columns (x, y)

3) return a ggvis plot displaying (x, y) from the uploaded data set

I've tried editing the examples from the Shiny Interactivity page as well as the movie explorer example. However, no chart is displayed.

I think my issue is around uploading the data set, but I don't know where to begin... Any suggestions?

Note - I've also tried this using rCharts, but I run into similar problems where no chart is displayed.

server.R

library(shiny)
library(dplyr)
library(ggvis)

shinyServer(function(input, output, session) {

fileHeaderNames <- reactive({

  infile <- input$datfile

  if(is.null(infile))
    return(NULL)

  d <- read.csv(infile$datapath, header = T)
  return(names(d))

})

# dynamic variable names
observe({

  updateSelectInput(session, 'x', choices = fileHeaderNames())
  updateSelectInput(session, 'y', choices = fileHeaderNames())

}) # end observe

  # uploading data set
  theData <- reactive({ 

    validate(
       need(input$datfile != "", "Please upload a file")
    )

    infile <- input$datfile
    dat <- read.csv(infile$datapath, 
                    header = T,
                    stringsAsFactors = F)

    if(is.null(infile)) return(NULL)

    data.frame(x = dat[, input$x],
               y = dat[, input$y])

    })

  # A simple visualisation. In shiny apps, need to register observers
  # and tell shiny where to put the controls
  theData %>%
    ggvis(~x, ~y) %>%
    layer_points() %>%
    bind_shiny("plot", "plot_ui")

})

ui.R

library(ggvis)
library(shiny)
shinyUI(pageWithSidebar(
  div(),
  sidebarPanel(
    fileInput('datfile', ''),
    selectInput('x', 'x:' ,'x'),
    selectInput('y', 'y:', 'y'),
    uiOutput("plot_ui")
  ),
  mainPanel(
    ggvisOutput("plot")
  )
))
maloneypatr
  • 3,562
  • 4
  • 23
  • 33
  • I can get this to work with googleVis, but I would like to use some features that are not available within that package. – maloneypatr Feb 11 '15 at 19:58

1 Answers1

5

Here is an attempt, I added a couple of reactive blocks to get the names that should be added on the plot axis.

A trick you can use is to create a filtered dataframe that has two columns x and y and that changes when the user changes the values in the selectInput. You can then tell ggvis to plot x and y from that filtered dataframe and the plot will be interactive.

library(shiny)
library(dplyr)
library(ggvis)

shinyServer(function(input, output, session) {
  #load the data when the user inputs a file
  theData <- reactive({
    infile <- input$datfile        
    if(is.null(infile))
      return(NULL)        
    d <- read.csv(infile$datapath, header = T)
    d        
  })



  # dynamic variable names
  observe({
    data<-theData()
    updateSelectInput(session, 'x', choices = names(data))
    updateSelectInput(session, 'y', choices = names(data))

  }) # end observe

  #gets the y variable name, will be used to change the plot legends
  yVarName<-reactive({
    input$y
  })

 #gets the x variable name, will be used to change the plot legends
  xVarName<-reactive({
    input$x
  })

  #make the filteredData frame

  filteredData<-reactive({
    data<-isolate(theData())
    #if there is no input, make a dummy dataframe
    if(input$x=="x" && input$y=="y"){
      if(is.null(data)){
        data<-data.frame(x=0,y=0)
      }
    }else{
      data<-data[,c(input$x,input$y)]
      names(data)<-c("x","y")
    }
    data
  })

  #plot the ggvis plot in a reactive block so that it changes with filteredData
  vis<-reactive({
    plotData<-filteredData()
    plotData %>%
    ggvis(~x, ~y) %>%
    layer_points() %>%
    add_axis("y", title = yVarName()) %>%
    add_axis("x", title = xVarName()) %>%
    add_tooltip(function(df) format(sqrt(df$x),digits=2))
  })
    vis%>%bind_shiny("plot", "plot_ui")

})

EDIT: added tooltips.

NicE
  • 21,165
  • 3
  • 51
  • 68
  • Hey @NicE, thanks so much for helping me out on this one! I never thought to put `data <- theData()` inside of the `observe` statement. The last thing I wanna do hear is add tooltips, I'm thinking it will work, but I may have to reach out if I can't. :p Thanks again! – maloneypatr Feb 12 '15 at 14:55
  • can you update this to demonstrate how tooltips would work? I am running into errors adding tooltips and editing the data. For instance, if I wanted to calculate the `sqrt(x)` instead of `x`, it doesn't work. Thanks again for your help! – maloneypatr Feb 18 '15 at 15:23
  • 1
    I added a tooltip line in the ggvis plot, when you hover over a point, you'll get a tooltip with the sqrt of the x value. The format is just to keep it to two digits. – NicE Feb 18 '15 at 15:50
  • I guess it's worth to emphasize that the empty dummy data.frame is crucial, otherwise the app will crash before the you had a chance to upload anything because NULL can't be processed by Vega (under the hood of ggvis). – Matt Bannert Mar 12 '16 at 19:26