Riddhi
Riddhi

Reputation: 93

Using a reactive function inside another reactive

I am new to reactive part of shiny. I have tried writing a code where there is a big reactive function and inside that I have another reactive function which changes on basis of a slider input. Is it possible to write one reactive inside other, because if it is my code doesn't run? Is it a good practice to write a reactive inside another reactive?

Here is my code:

dt <- reactive({
    con = dbConnect(MySQL(), user='root', password='root', db='simulator', host='localhost')
    size <- reactive({dbGetQuery( con, statement = paste(" Select count(*) from event where event_type = 'pe_send_flit' and run_id = ",input$run))})
    j = (size()$`count(*)`) - 1
    a <- j
    b <- j
    for(i in 0:j)
    {
      a[i] <- dbGetQuery(con, statement = paste(" Select event_time from event where event_type = 'pe_receive_flit' and run_id = ",input$run," and event_data =", i,"order by event_data asc"))
      b[i] <- dbGetQuery(con, statement = paste(" Select event_time from event where event_type = 'pe_send_flit' and run_id = ",input$run," and event_data =",i,"order by event_data asc"))
    }
    receive <- as.vector(a,mode='numeric')
    send <- as.vector(b,mode='numeric')
    difference = receive - send
    len = length(difference)
    avg = 0.0
    sum_f = 0
    counter = 1
    xrange <- vector(mode = "numeric", length = len)
    yrange <- vector(mode = "numeric", length = len)
    for (k in 1:len)
    {
      temp = receive[k]
      sum_f = difference[k]
      l = k + 1
      for(m in l:len)
      {
        if(isTRUE(all.equal(temp,receive[m])))
        {
          sum_f = sum_f + difference[m]
          counter = counter + 1
          receive[m] = 0
          difference[m] = 0
        }
      }
      avg = sum_f/counter
      xrange[k] = receive[k]
      yrange[k] = avg
    }
    xrange <- xrange[xrange!=0]
    yrange <- yrange[yrange!=0.000]
    xrange <- xrange[!is.na(xrange)]
    yrange <- yrange[!is.na(yrange)]
    array_length = length(xrange)
    ind <- sort(xrange,index.return = TRUE)$ix
    xrange <- xrange[ind]
    yrange <- yrange[ind]
    myfunction <- function(pa,val,x)
    {
      y = x - 1
      tmp = pa*y
      sm = tmp + val
      incr = y + 1
      result = sm/incr
      return(result)
    }
    incremental_average <- vector(mode = "numeric",length = array_length)
    pa = as.integer(0)
    for(r in 1:array_length)
    {
      pa = myfunction(pa,yrange[r],r)
      incremental_average[r] = pa
    }
    dbDisconnect(con)
    df <- data.frame(xrange,incremental_average)
    dat <- reactive({
      if(!is.null(input$range))
      {
        test <- df[df$xrange %in% seq(from=input$range[1],to=input$range[2]),]
        test
      }
    })

    df
  })

How do I use the 'dat' reactive part?

Upvotes: 2

Views: 2768

Answers (1)

Gladwell
Gladwell

Reputation: 328

Pull this bit out and rewrite as

dat <- reactive({
    if(!is.null(input$range)) {
        test <- dt()[dt()$xrange %in% seq(from=input$range[1],to=input$range[2]),]
        test
    }
})

Now your dt() function returns the data (effectively just loading it) but your dat() function returns the filtered data.

Upvotes: 1

Related Questions