I am a beginner to programming, R, shiny, and ggvis, trying to wrap my head around reactive data updating based on user input. Below is a reproducible example of a shiny App containing a time course plot of the type I am trying to build.
The app should run, and should update upon the change of user input. However, the plot only updates when the x, y, and size variables are called in the ggvis() call using the "mapping" syntax ( = ). My intuition is that the use of the "setting" syntax ( := ) or the ( ~ ) operator would help solve the following problem:
The problem is that instead of a new plot being generated when the user input is changed, and that new plot being sent to the client, I would like the data points to update dynamically - fly across the plot to their new (x,y,size) position.
I'm not yet syntactically comfortable with how ggvis binds a given data point (with x, y, and size values taken from individual columns of a data frame) to an updated data point (of three different columns in the same row of that data frame). Is there currently functionality in ggvis that allows for the kind of update I am looking for?
ui.R
library(shiny)
library(ggvis)
shinyUI(pageWithSidebar(
headerPanel=headerPanel("Reactive Data Update Problem"),
sidebarPanel=sidebarPanel(
selectInput("timePoint",
"Choose Time Point:",
list("time1" = 1,
"time2" = 2
)
)
),
mainPanel=mainPanel(
tabsetPanel(
tabPanel('Plot',
ggvis_output("myDotPlot")),
tabPanel('Table',
dataTableOutput("myDataTable"))
)
)
)
)
server.R
library(shiny)
library(ggvis)
# Create sample dataset
time1x <- rexp(500, 2)
time1y <- rexp(500, 1)
time1s <- abs(log2(time1x/time1y))
time2x <- rexp(500, .02)
time2y <- rexp(500, .01)
time2s <- abs(log2(time2x/time2y))
myDataTable <- data.frame( "time1x" = time1x
, "time1y" = time1y
, "time1s" = time1s
, "time2x" = time2x
, "time2y" = time2y
, "time2s" = time2s
)
# Define paster functions allowing an input integer to represent a d.f column
xFormat <- function(timePoint) { paste("time", timePoint, "x", sep = "") }
yFormat <- function(timePoint) { paste("time", timePoint, "y", sep = "") }
sFormat <- function(timePoint) { paste("time", timePoint, "s", sep = "") }
# Define server logic necessary to produce plot
shinyServer(function(input, output, session){
myDotPlot <- reactive({
ggvis(myDataTable, props( x = as.name(xFormat(input$timePoint))
, y = as.name(yFormat(input$timePoint))
, size = as.name(sFormat(input$timePoint))
)
) + mark_point()
})
output$myDataTable = renderDataTable({myDataTable})
observe_ggvis(myDotPlot, 'myDotPlot', session)
})