I liked the idea of Shiny and being able to deploy an app easily via Shiny Server. Therefore, I tried the installation and app creation process out myself.
Here is the final result. Try to estimate the time span of 4 seconds!
The installation of Shiny Server is very nicely explained here. The following commands are sufficient for my Ubuntu server.
1 2 3 4 5 6 |
[shell] sudo apt-get install r-base sudo apt-get install gdebi-core wget https://download2.rstudio.org/rstudio-server-1.1.456-amd64.deb sudo gdebi rstudio-server-1.1.456-amd64.deb [/shell] |
Useful to restart the Shiny Server was also
1 |
[shell]sudo systemctl restart shiny-server[/shell] |
I changed the port to be used from the default port to the port 9998 in the config file, found at
1 |
[shell] /etc/shiny-server/shiny-server.conf [/shell] |
All .R files for the first app live under /srv/shiny-server/sample-apps/timeestimate. Since I read and write data to /srv/shiny-server/sample-apps/timeestimate/data I had to give write access to shiny via
1 2 |
[shell] sudo chown -R shiny:shiny /srv/shiny-server/sample-apps/timeestimate/data/ [/shell] |
I wanted to create an app, that lets users guess the time span of four seconds. Therefore I needed just one button that changes from a start to a stop button regarding of what it was before and a way to display the data. Here are the ui.R file and the server.R file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[shell] library(shiny) ui <- fluidPage( actionButton("timerbutton", "Click to start timer"), hr(), textOutput("result"), hr(), textOutput("resultsummary1"), hr(), textOutput("resultsummary2"), hr(), plotOutput("plot") ) [/shell] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
[shell] library(shiny) server <- function(input, output,session){ v <- reactiveValues(data = NULL) observeEvent(input$timerbutton, { if (is.null(v$started)){ # if not initialized, i.e. first v$started = FALSE } if (v$started==FALSE){ updateActionButton(session, "timerbutton", label = "Click to stop timer") v<- Sys.time(); }else{ updateActionButton(session, "timerbutton", label = "Click to start timer") dt<- Sys.time()-v$t; data <-read.csv("/srv/shiny-server/sample-apps/timeestimate/data/dt.csv",header = TRUE) if (is.null(v$data)){ v$data = dt }else{ v$data<- c(v$data,dt) } dts <- c(data$x,dt) write.csv(dts,"/srv/shiny-server/sample-apps/timeestimate/data/dt.csv",row.names = FALSE) output$plot <- renderPlot({ x <-as.numeric(dts) v$n = length(x) v$x = x bins <- seq(0,8, length.out = 41) hist(x, breaks = bins, col = "#75AADB", border = "white", xlab = "time t in seconds", main = "Estimating how long 4 seconds take") }) output$result <- renderText({ paste(c("You estimated 4 seconds as:", dt), collapse = " ") }) output$resultsummary2<- renderText({ paste(c("Mean =", mean(v$x)), collapse = " ") }) output$resultsummary1 <- renderText({ paste(c("Sample size =", v$n), collapse = " ") }) #output$show = TRUE } v$started=!(v$started) }) } [/shell] |
One thing that is not here in the code as I edited it later: I throw away outliers where people estimate the time as 8 seconds or more as this screw the histogram creation.
I want to analyze the output in the future. However, there is some delay with the whole process, so it might be more optimal to move the timing to the client side. For the current version, a histogram is shown below.
