Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue controlling the ncharts, nrow and ncol options of the compareOptions function via shiny input #44

Closed
cegbuna opened this issue Oct 11, 2017 · 3 comments

Comments

@cegbuna
Copy link

cegbuna commented Oct 11, 2017

Hi,

I'm trying to control the .compareOpts argument in the manipulateWidget package, specifically the
ncharts, nrow and ncol arguments of the compareOptions function via shiny inputs, specifically, sliderInput. I have tried using the code snippet below, but I keep getting error messages.

Code

require(shiny)
require(dygraphs)
require(pipeR)
require(manipulateWidget)
ui <- fillPage(
  fillRow(
    flex = c(NA, 1),
    div(
      textInput("title", label = "Title", value = "glop"),
      sliderInput("obs", "Number of observations:",
                  min = 10, max = 1000, value = 500),
      sliderInput("ncharts", label = "Select number of charts to view", min = 1, max = 6, step = 1, value = 8),
      sliderInput("nrow", label = "Select number of rows to view", min = 1, max = 6, step = 1, value = 4),
      sliderInput("ncol", label = "Select number of columns to view", min = 1, max = 6, step = 1, value = 3)
    ),
    mwModuleUI("ui", height = "100%")
  )
)

server <- function(input, output, session) {

  data <- reactive({
    if(runif(1) > 0.5){
      data.frame(
        year = 2000+1:input$obs,
        series1 = rnorm(input$obs),
        series2 = rnorm(input$obs),
        series3 = rnorm(input$obs)
      )
    } else {
      data.frame(
        year = 2000+1:input$obs,
        series1 = rnorm(input$obs),
        series2 = rnorm(input$obs)
      )
    }
    
  })

  c <- manipulateWidget(
    {  
      dygraph(data[range[1]:range[2] - 2000, c("year", series)], main = title)
    },
    range = mwSlider(min = 2001, max = 2001 + (nrow(data)-1), c(2001, 2001 + (nrow(data)-1))),
    series = mwSelect(choices = colnames(data)[-1], value = colnames(data)[3]),
    title = mwSharedValue(),
    data = mwSharedValue(), .runApp = FALSE,
    .compare = "range",
    .compareOpts = compareOptions(ncharts = input$ncharts, nrow = input$nrow, ncol = input$ncol)
  )
  mwModule("ui", c, title = reactive(input$title), data = data)
}

shinyApp(ui, server)

Error message

Error in .getReactiveEnvironment()$currentContext() : 
  Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)

I've also tried to add sliders for ncharts, nrow and ncol arguments to the manipulateWidget gadget in the code below but still get errors.

Code

c <- manipulateWidget(
    {  
      dygraph(data[range[1]:range[2] - 2000, c("year", series)], main = title)
    },
    range = mwSlider(min = 2001, max = 2001 + (nrow(data)-1), c(2001, 2001 + (nrow(data)-1))),
    series = mwSelect(choices = colnames(data)[-1], value = colnames(data)[3]),
    title = mwSharedValue(),
    ncharts = mwSlider(min = 1, max = 10, value = 4),
    nrow = mwSlider(min = 1, max = 10, value = 4),
    ncol = mwSlider(min = 1, max = 10, value = 4),
    data = mwSharedValue(), .runApp = FALSE,
    .compare = "range",
    .compareOpts = compareOptions(ncharts = "ncharts", nrow = "nrow", ncol = "ncol")
  )
  mwModule("ui", c, title = reactive(input$title), 
           ncharts = reactive(input$ncharts), 
           ncol = reactive(input$mcol), 
           nrow = reactive(input$nrow),
           data = data)

Error

Warning: Error in *: non-numeric argument to binary operator
Stack trace (innermost first):
    39: .getRowAndCols
    38: manipulateWidget
    37: server [C:/Users/jla995/Documents/Work Projects/R - Panel Plots in Shiny.R#41]
     1: runApp
Error in nrow * ncol : non-numeric argument to binary operator

When I create a separate arguments for the 3 parameters like below, the app works but this isn't what I want. I would like for the user to have the ability to change the number and layout of the charts as they see fit.

ncharts = 10
nrow = 4
ncol = 3

Session info

R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] manipulateWidget_0.8.0 pipeR_0.6.1.3          dygraphs_1.1.1.4       shiny_1.0.5            rAmCharts_2.1.5       

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.12      lattice_0.20-35   zoo_1.8-0         digest_0.6.12     mime_0.5          grid_3.4.0        R6_2.2.2          xtable_1.8-2     
 [9] magrittr_1.5      miniUI_0.1.1      data.table_1.10.4 tools_3.4.0       htmlwidgets_0.9   httpuv_1.3.5      yaml_2.1.14       compiler_3.4.0   
[17] htmltools_0.3.6

I appreciate any help to get this working?
Thanks.

@cegbuna
Copy link
Author

cegbuna commented Oct 18, 2017

Hi, have you had a chance to take a look at this issue? Thanks!

@bthieurmel
Copy link
Collaborator

Hi,

You can have the result you want using an observe :

server <- function(input, output, session) {
  
  data <- reactive({
    if(runif(1) > 0.5){
      data.frame(
        year = 2000+1:input$obs,
        series1 = rnorm(input$obs),
        series2 = rnorm(input$obs),
        series3 = rnorm(input$obs)
      )
    } else {
      data.frame(
        year = 2000+1:input$obs,
        series1 = rnorm(input$obs),
        series2 = rnorm(input$obs)
      )
    }
    
  })
  
  observe({
    ncharts = input$ncharts
    nrow = input$nrow
    ncol = input$ncol
    
    c <- manipulateWidget(
      {  
        dygraph(data[range[1]:range[2] - 2000, c("year", series)], main = title)
      },
      range = mwSlider(min = 2001, max = 2001 + (nrow(data)-1), c(2001, 2001 + (nrow(data)-1))),
      series = mwSelect(choices = colnames(data)[-1], value = colnames(data)[3]),
      title = mwSharedValue(),
      data = mwSharedValue(), .runApp = FALSE,
      .compare = "range",
      .compareOpts = compareOptions(ncharts = ncharts, nrow = nrow, ncol = ncol)
    )
    mwModule("ui", c, title = reactive(input$title), data = data)
  })
  
}

@cegbuna
Copy link
Author

cegbuna commented Oct 26, 2017

Thanks for the response @bthieurmel. Your solution worked. I have another question though. I have multiple graphs, some from different packages and would like the option to chose which goes to which panel. I tried adding them below the dygraph(data[range[1]:range[2] - 2000, c("year", series)], main = title) line but it didn't work. Could you please advice on an alternative solution. Thanks again for taking the time to respond.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants