I am new to Shiny, and I need to know how to use a button to retrigger shinyServer({}) even with no new input.
I have a function makeTrace() which creates a random time series with certain features. I just want to write a simple Shiny App to present the time series along with a button that calls makeTrace again to redo the time series so the viewer can see as many as he likes by pressing the button repeatedly. The randomization is in the makeTrace function so all I need my shiny to do is call this function.
The only way I got this to work was to add another input and link the button and the plot by way of that input, but this isn't really what I want:
server.R
source("helpers.R")
shinyServer(function(input, output) {
# builds a reactive expression that only invalidates
# when the value of input$goButton becomes out of date
# (i.e., when the button is pressed)
ntext <- eventReactive(input$goButton, {
output$trace <- renderPlot({
plot(makeTrace())
})
input$n
})
output$nText <- renderText({
ntext()
})
})
and ui.R
shinyUI(pageWithSidebar(
headerPanel("actionButton test"),
sidebarPanel(
numericInput("n", "N:", min = 0, max = 100, value = 50),
br(),
actionButton("goButton", "Go!"),
p("Click the button to update the value displayed in the main panel.")
),
mainPanel(
verbatimTextOutput("nText"),
plotOutput("trace")
)
))
And I will paste helpers.R at bottom if you want to run it.
So if you run this, you'll see the display does update with a new time series, but the problem is I want to do this without the hack of having some fake input I am using as a fake parameter. I really just want to press a button and make the plot(makeTrace()) get called again, because as I said, makeTrace() takes care of creating new/random data each time it's called.
Thanks.
helpers.R
#MAKE STEPS WITHIN A CONDUCTANCE STEP
makeSteps <- function(lowG, highG, num.G.groups = 3, max.steps = max.steps.const, mean.step.p = 300, sd.step.p = 100, temp=0){
#decide how many within conductance plateau events there are for this plateau and segment conductance into boxes
mid <- rnorm(2, mean = (lowG + highG)/2, sd = (lowG + highG)/5)
conductance.boxes <- seq(from=min(mid), to=max(mid), length.out = num.G.groups)
numSteps <- sample(1:max.steps, 1)
#choose conductance and step length for each step
#enforce G values that are physically realistic, no higher or lower than cutoff values
stepsG <- rnorm(numSteps, mean = (lowG + highG)/2, sd = (lowG + highG)/5)
stepsG <- replace(stepsG, stepsG<lowG, lowG)
stepsG <- replace(stepsG, stepsG>highG, highG)
stepsL <- floor(abs(rnorm(n = numSteps, mean = mean.step.p, sd=sd.step.p)))
#prepare entire molecular step
trace <- c(1:sum(stepsL))
startp <- 1
for(i in 1:length(stepsL)){
endp <- startp + stepsL[i] - 1
trace[startp:endp] <- rnorm(n=stepsL[i], mean = stepsG[i], sd = stepsG[i]/12)
startp <- startp + stepsL[i]
}
trace
}
# MAKES TRACES WITH A MOLECULAR STEP
makeTrace <- function(molG=10^-4, molSD=10^-4, excursion=5, GDist=.5, numP=numPconst, multiples=FALSE, temp=0, shiny=0){
#make 3,2,1 G0 steps that have within-plateau events if temp = 0, otherwise they are relatively flat
g3 <- makeSteps(lowG=2.1, highG=2.5, temp=temp)
g2 <- makeSteps(lowG=1.4, highG=min(g3), temp=temp)
g1 <- makeSteps(lowG=.5, highG=min(g2), temp=temp)
#length measured in points
g1stepL <- length(g1)
g2stepL <- length(g2)
g3stepL <- length(g3)
#conversion between nm and indices
delX <- numP/excursion
dt <- seq(from = 0 , to = excursion, excursion/numP)
#store conductance time series in g (G for conductance)
g <- c(1:numP + 1)
offset <- 0
#assign 3,2,1 G0 steps generated earlier individually to single time series
g[(1 + offset) : (g3stepL + offset)] <- g3
offset <- g3stepL + offset
g[(1 + offset) : (g2stepL + offset)] <- g2
offset <- g2stepL + offset
g[(1 + offset) : (g1stepL + offset)] <- g1
offset <- g1stepL + offset
#metallic junction breaks to electronics noise level
g[(offset):numP + 1] <- rnorm(n=(numP-offset+1),mean=10^-5, sd = 10^-5)
#subtract out negative noise so all values positive
m <- min(g)
g <- g - m +.000001
g <- remove.repeat.NA(trace.smooth(g, type="moving-average", width=5))
df <- data.frame(Displacement=dt,Conductance=g, check.names = FALSE, row.names = NULL)
}