3

This is an extension of the question

How to isolate the output of a reactive (function) and save to a data.frame?

Basically I want to construct a table based on a vector with predetermined and added values. I want to show as tableoutput the original vector and a column with the roll mean of the previous 4 values of this vector. For instance, if the user added the value 200, I will have

d <- c(rep(100,4),200) 

and using zoo::rollapply() I have the roll mean of the previous 4 values of d

md <- rollapply(d , mean , fill = NA, width = list(-1:-4))

the expected result

cbind(d,md)

       d  md
[1,] 100  NA
[2,] 100  NA
[3,] 100  NA
[4,] 100  NA
[5,] 200 100

In my shiny app I am not able to use my function, the app close when I add a value. But if I use other function like input$c1 + 5 it works. I think that the problem is that I do not know how to capture the updated vector and use it to run a function that needs a vector as input. Furthermore, to run the app I needed to match the same number of rows in the new column.

Here is my UI code:

library(shiny)

fluidPage(
  sidebarPanel(textInput("c1","example"),

           actionButton("update", "Update Table")
  ),

 mainPanel(tableOutput("example")

 )
)

and the server

library(shiny)
library(zoo)

function(input, output) {

  #Example
  d <- c(rep(100,4))
  m <- c(rep(100,4))

  md <- reactive(
 rollapply(values$df , mean , fill=NA , width=list(-1:-4))
 )

  values <- reactiveValues(df = data.frame('D' = d, 'M_D'= m))
  newEntry <- observe({
    if(input$update > 0) {
        values$df <- isolate(rbind(values$df,data.frame('D' =input$c1, 
   'M_D' = md())))
    }
  })

  output$example <- renderTable({values$df})

} 
msmarchena
  • 103
  • 2
  • 13

1 Answers1

4

So I would say were using too many different shiny mechanisms and they were tripping over each other. I made the following changes:

  • changed observe to observeEvent so as to confine the calculations to when you pres the update button.
  • did away with the isolate usage as it is not needed in an observeEvent as opposed to an observe.
  • got rid of the reactive md() function as you already have that data stored in a reactiveValues list.
  • made the rollingapply operate only on the relevant columns instead of the entire data frame.
  • cleaned up the syntax a bit - got rid if extraneous quotes, c() in c(rep(...)), etc.
  • compressed it a bit.
  • added the as.numeric to the input$c1 processing otherwise it was causing that column to convert to a factor and change its values.

So here is the code:

library(shiny)
library(zoo)

u <- fluidPage(
  sidebarPanel(textInput("c1","example"),
               actionButton("update", "Update Table")
  ),
  mainPanel(tableOutput("example")
  )
)
s <- function(input, output) {

  #Example
  d <- rep(100,4)
  m <- rep(100,4)

  values <- reactiveValues(df = data.frame(D=d, M_D=m))

  newEntry <- observeEvent(input$update,{
    d_new <- c(values$df$D,as.numeric(input$c1))
    m_d_new <- rollapply(d_new, mean , fill=NA , width=list(-1:-4))
    values$df <- data.frame(D=d_new,M_D=m_d_new)
  })
  output$example <- renderTable({values$df})
} 
shinyApp(u,s)

Which yields the following after entering 200 and pressing Update Table a few times:

enter image description here

Mike Wise
  • 22,131
  • 8
  • 81
  • 104
  • 1
    Thanks Mike, it was exactly what I needed. I was confusing about how to use reactive and observe function in this context and I didn’t know how to call the column of the dataframe (values$df$D).This is my first app. – msmarchena Jun 05 '17 at 11:14
  • You got pretty far for your first Shiny app. This kind of programming (reactive) is very different than what you usually see. I would ask you to consider dropping an upvote here too when you get to 15 points. – Mike Wise Jun 05 '17 at 11:31
  • Of course, now I have not enough points to vote. But I will do that for sure. I have edited my original post. Please help me. – msmarchena Jun 05 '17 at 13:22
  • Please ask a new question in these cases. Otherwise things get too confused. Also gives you a chance to earn more points. – Mike Wise Jun 05 '17 at 13:32
  • 1
    Ok, sorry. I did not know how it works. I am new in stackoverflow too. I will do that. – msmarchena Jun 05 '17 at 13:39
  • Also you don't need to name me or anything. Assume anyone will help you, and they don't really care who helped you before. There are lots of people out there who can help. Andy they will happily do so for accepted answers and upvotes. – Mike Wise Jun 05 '17 at 13:45