No lines available in input

shiny

#1

Hello,

I am having trouble getting to the bottom of an error that is occurring in my code.

Overview of my code:
I am receiving accellerometer data which is being written to a file as it comes in, this file is then read and plotted by r code as well as a message depending on the average of the data (Note the data file writes over itself after 200 entries, this part is functional).

Key notes about the problem:
The error occurs randomly at any time, I have 8 plots running at once, some will get an error almost immediately others have lasted up to an hours before getting the error.

I have watched and waited for the error to stop and inspect the most recent incoming messages to find nothing out of the ordinary.

There are two places where the error is happening, in the plot and in the "status" box next to the plot, the error occurs in no particular order or pattern.

The code:
server.r:

library(shinydashboard)
library(readr)
library(ggplot2)

Shinyserver <- function(input, output, session) {
  # Output sidebarpanel detail to UI  -------------------------------------------

  
  
  
  # Output body detail to UI  -------------------------------------------    
  output$body <- renderUI({
    tags$style(type="text/css",
".recalculating {opacity: 1.0;}"
)
    div(width=12,
        
        # Info Boxes --------------------------------------------------------------

        
        
       
        fluidRow(tags$style(type="text/css", ".recalculating {opacity: 1.0;}"),
	  box(height= 400, width=10, plotOutput("plot1", height=350)),
          valueBoxOutput("activity1", width = 2)),
	  fluidRow(tags$style(type="text/css", ".recalculating {opacity: 1.0;}"),
	           box(title=h3("Activity Tracking A02"), height= 400, width=10, plotOutput("plot2", height=250)),
	           valueBoxOutput("activity2", width = 2)),
	  fluidRow(tags$style(type="text/css", ".recalculating {opacity: 1.0;}"),
	           box(title=h3("Activity Tracking A03"), height= 400, width=10, plotOutput("plot3", height=250)),
	           valueBoxOutput("activity3", width = 2)),
	  fluidRow(tags$style(type="text/css", ".recalculating {opacity: 1.0;}"),
	           box(title=h3("Activity Tracking A04"), height= 400, width=10, plotOutput("plot4", height=250)),
	           valueBoxOutput("activity4", width = 2)),
	  fluidRow(tags$style(type="text/css", ".recalculating {opacity: 1.0;}"),
	           box(title=h3("Activity Tracking A05"), height= 400, width=10, plotOutput("plot5", height=250)),
	           valueBoxOutput("activity5", width = 2)),	  
	   fluidRow(tags$style(type="text/css", ".recalculating {opacity: 1.0;}"),
	            box(title=h3("Activity Tracking A06"), height= 400, width=10, plotOutput("plot6", height=250)),
	            valueBoxOutput("activity6", width = 2)),
	   fluidRow(tags$style(type="text/css", ".recalculating {opacity: 1.0;}"),
	            box(title=h3("Activity Tracking A07"), height= 400, width=10, plotOutput("plot7", height=250)),
	            valueBoxOutput("activity7", width = 2)),
	   fluidRow(tags$style(type="text/css", ".recalculating {opacity: 1.0;}"),
	            box(title=h3("Activity Tracking A08"), height= 400, width=10, plotOutput("plot8", height=250)),
	            valueBoxOutput("activity8", width = 2)))
    
     })
 
  
  autoInvalidate <- reactiveTimer(20)
  
  # Generate a new histogram each time the timer fires, but not when
  # input$n changes.
  
  output$plot1 <- renderPlot({
   autoInvalidate()
    
 	chuck1 <- read.csv("logfile1.txt",header=FALSE)
    autoInvalidate()
 	chuck1 <- na.omit(chuck1)
    	plot(chuck1$V1,chuck1$V2, type="o", xlab="Time in seconds", ylab="Movement", main="Module 1", ylim=c(0.5,4))


  })
  # Generating the second plot
  output$plot2 <- renderPlot({

    
    chuck2 <- read.csv("logfile2.txt",header=FALSE)
    autoInvalidate()
    chuck2 <- na.omit(chuck2)
    plot(chuck2$V1,chuck2$V2, type="o")
    
  })
  
  # Generating the third plot
  output$plot3 <- renderPlot({
    
    
    chuck3 <- read.csv("logfile3.txt",header=FALSE)
    autoInvalidate()
    chuck3 <- na.omit(chuck3)
    plot(chuck3$V1,chuck3$V2, type="o")
    
  })
  
  # Generating the fourth plot
  output$plot4 <- renderPlot({
    
    
    chuck4 <- read.csv("logfile4.txt",header=FALSE)
    autoInvalidate()
    chuck4 <- na.omit(chuck4)
    plot(chuck4$V1,chuck4$V2, type="o")
    
  })
  
  # Generating the second plot
  output$plot5 <- renderPlot({
    
    
    chuck5 <- read.csv("logfile5.txt",header=FALSE)
    autoInvalidate()
    chuck5 <- na.omit(chuck5)
    plot(chuck5$V1,chuck5$V2, type="o")
    
  })
  
 #  Generating the second plot
   output$plot6 <- renderPlot({
    
  
   chuck6 <- read.csv("logfile6.txt",header=FALSE)
   autoInvalidate()
   chuck6 <- na.omit(chuck6)
   plot(chuck6$V1,chuck6$V2, type="o")
     
   })
   
  # Generating the second plot
  output$plot7 <- renderPlot({
     
    
   chuck7 <- read.csv("logfile7.txt",header=FALSE)
   autoInvalidate()
   chuck7 <- na.omit(chuck7)
    plot(chuck7$V1,chuck7$V2, type="o")
   
  })
   
 # Generating the second plot
 output$plot8 <- renderPlot({
   
   
    chuck8 <- read.csv("logfile8.txt",header=FALSE)
    autoInvalidate()
    chuck8 <- na.omit(chuck8)
    plot(chuck8$V1,chuck8$V2, type="o")
  
  })
  
  #Add this in late because its flickering now       tags$img(src="20170209_133428 small.jpg",height = 230, width = 230)
  
 output$activity1 <- renderInfoBox({ 


  activity_level_math1 <- read.csv("logfile1.txt", header=FALSE)
autoInvalidate()
activity_level_math1 <-na.omit(activity_level_math1)
  activity_level1 <<- mean(activity_level_math1$V2)
 (if(activity_level1 > 0.95 && activity_level1 < 1.05)

    { 
      box(width=2, height = 400, box(width = 12, height = 125, background = "yellow", h3("The tag isn't moving"), h4("Wake up!!")), sprintf("Av: %f", activity_level1))
    }
  else if (activity_level1 > 1 & activity_level1 < 2)
  { 
    box(width=2, height = 400, box(width = 12, height = 125, background = "green", h3("You're doing OK"), h4("Keep it up!!")), sprintf("Av: %f", activity_level1))
  }
  else if (activity_level1 > 2)
  { 
    box(width=2, height = 400, box(width = 12, height = 125, background = "red", h3("You're Too Active"), h4("Slow Down!!")), sprintf("Av: %f", activity_level1))
  })
})

 output$activity2 <- renderInfoBox({ 
   
   
   activity_level_math2 <- read.csv("logfile2.txt", header=FALSE)
   autoInvalidate()
activity_level_math2 <-na.omit(activity_level_math2)
   activity_level2 <<- mean(activity_level_math2$V2)
   (if(activity_level2 > 0.95 && activity_level2 < 1.05)
     
   { 
     box(width=2, height = 400, box(width = 12, height = 125, background = "yellow", h3("The tag isn't moving"), h4("Wake up!!")), sprintf("Av: %f", activity_level2))
   }
     else if (activity_level2 > 1 && activity_level2 < 2)
     { 
       box(width=2, height = 400, box(width = 12, height = 125, background = "green", h3("You're doing OK"), h4("Keep it up!!")), sprintf("Av: %f", activity_level2))
     }
     else if (activity_level2 > 2)
     { 
       box(width=2, height = 400, box(width = 12, height = 125, background = "red", h3("You're Too Active"), h4("Slow Down!!")), sprintf("Av: %f", activity_level2))
     })
 })
 
 output$activity3 <- renderInfoBox({ 
   
   
   activity_level_math3 <- read.csv("logfile3.txt", header=FALSE)
   autoInvalidate()
   activity_level3 <<- mean(activity_level_math3$V2)
   (if(activity_level3 > 0.95 && activity_level3 < 1.05)
     
   { 
     box(width=2, height = 400, box(width = 12, height = 125, background = "yellow", h3("The tag isn't moving"), h4("Wake up!!")), sprintf("Av: %f", activity_level3))
   }
     else if (activity_level3 > 1 && activity_level3 < 2)
     { 
       box(width=2, height = 400, box(width = 12, height = 125, background = "green", h3("You're doing OK"), h4("Keep it up!!")), sprintf("Av: %f", activity_level3))
     }
     else if (activity_level3 > 2)
     { 
       box(width=2, height = 400, box(width = 12, height = 125, background = "red", h3("You're Too Active"), h4("Slow Down!!")), sprintf("Av: %f", activity_level3))
     })
 })
 
 output$activity4 <- renderInfoBox({ 
   
   
   activity_level_math4 <- read.csv("logfile4.txt", header=FALSE)
   autoInvalidate()
   activity_level4 <<- mean(activity_level_math4$V2)
   (if(activity_level4 > 0.95 && activity_level4 < 1.05)
     
   { 
     box(width=2, height = 400, box(width = 12, height = 125, background = "yellow", h3("The tag isn't moving"), h4("Wake up!!")), sprintf("Av: %f", activity_level4))
   }
     else if (activity_level4 > 1 && activity_level4 < 2)
     { 
       box(width=2, height = 400, box(width = 12, height = 125, background = "green", h3("You're doing OK"), h4("Keep it up!!")), sprintf("Av: %f", activity_level4))
     }
     else if (activity_level4 > 2)
     { 
       box(width=2, height = 400, box(width = 12, height = 125, background = "red", h3("You're Too Active"), h4("Slow Down!!")), sprintf("Av: %f", activity_level4))
     })
 })
 
 output$activity5 <- renderInfoBox({ 
   
   
   activity_level_math5 <- read.csv("logfile5.txt", header=FALSE)
   autoInvalidate()
   activity_level5 <<- mean(activity_level_math5$V2)
   (if(activity_level5 > 0.95 && activity_level5 < 1.05)
     
   { 
     box(width=2, height = 400, box(width = 12, height = 125, background = "yellow", h3("The tag isn't moving"), h4("Wake up!!")), sprintf("Av: %f", activity_level5))
   }
     else if (activity_level5 > 1 && activity_level5 < 2)
     { 
       box(width=2, height = 400, box(width = 12, height = 125, background = "green", h3("You're doing OK"), h4("Keep it up!!")), sprintf("Av: %f", activity_level5))
     }
     else if (activity_level5 > 2)
     { 
       box(width=2, height = 400, box(width = 12, height = 125, background = "red", h3("You're Too Active"), h4("Slow Down!!")), sprintf("Av: %f", activity_level5))
     })
 })
 
 output$activity6 <- renderInfoBox({
 
 
   activity_level_math6 <- read.csv("logfile6.txt", header=FALSE)
   autoInvalidate()
   activity_level6 <<- mean(activity_level_math6$V2)
   (if(activity_level6 > 0.95 && activity_level6 < 1.05)
 
   {
     box(width=2, height = 400, box(width = 12, height = 125, background = "yellow", h3("The tag isn't moving"), h4("Wake up!!")), sprintf("Av: %f", activity_level6))
   }
     else if (activity_level6 > 1 && activity_level6 < 2)
   {
       box(width=2, height = 400, box(width = 12, height = 125, background = "green", h3("You're doing OK"), h4("Keep it up!!")), sprintf("Av: %f", activity_level6))
     }
     else if (activity_level6 > 2)
     {
       box(width=2, height = 400, box(width = 12, height = 125, background = "red", h3("You're Too Active"), h4("Slow Down!!")), sprintf("Av: %f", activity_level6))
     })
 })
  
 output$activity7 <- renderInfoBox({
  
 
    activity_level_math7 <- read.csv("logfile7.txt", header=FALSE)
  autoInvalidate()
    activity_level7 <<- mean(activity_level_math7$V2)
    (if(activity_level7 > 0.95 && activity_level7 < 1.05)
  
    {
     box(width=2, height = 400, box(width = 12, height = 125, background = "yellow", h3("The tag isn't moving"), h4("Wake up!!")), sprintf("Av: %f", activity_level7))
   }
      else if (activity_level7 > 1 && activity_level7 < 2)
    {
        box(width=2, height = 400, box(width = 12, height = 125, background = "green", h3("You're doing OK"), h4("Keep it up!!")), sprintf("Av: %f", activity_level7))
     }
      else if (activity_level7 > 2)
     {
        box(width=2, height = 400, box(width = 12, height = 125, background = "red", h3("You're Too Active"), h4("Slow Down!!")), sprintf("Av: %f", activity_level7))
      })
  })
  
  output$activity8 <- renderInfoBox({
  
  
    activity_level_math8 <- read.csv("logfile8.txt", header=FALSE)
    autoInvalidate()
    activity_level8 <<- mean(activity_level_math8$V2)
    (if(activity_level8 > 0.95 && activity_level8 < 1.05)
  
    {
      box(width=2, height = 400, box(width = 12, height = 125, background = "yellow", h3("The tag isn't moving"), h4("Wake up!!")), sprintf("Av: %f", activity_level8))
    }
      else if (activity_level8 > 1 && activity_level8 < 2)
      {
        box(width=2, height = 400, box(width = 12, height = 125, background = "green", h3("You're doing OK"), h4("Keep it up!!")), sprintf("Av: %f", activity_level8))
      }
      else if (activity_level8 > 2)
      {
        box(width=2, height = 400, box(width = 12, height = 125, background = "red", h3("You're Too Active"), h4("Slow Down!!")), sprintf("Av: %f", activity_level8))
      })
  })

 
}

The Ui.r:

library(shiny)
library(shinydashboard)

header <- dashboardHeader(dropdownMenuOutput("notificationsMenu"), title = tags$a(href='Ignore this',
                                                                                  tags$img(src="DM1.png", height = 35, width = 110)), titleWidth = 250)
sidebar <- dashboardSidebar(disable=TRUE, uiOutput("sidebarpanel"))

body <- dashboardBody(uiOutput("body"))

ui <- dashboardPage(skin="black",header, sidebar, body)

All suggestions are welcome, thankyou in advance.

Cheers,
Dylan

PS: I am aware that the first valuebox is different to the other, it's the one I've been testing different visual parts too instead of changing all of them every time. But if you are willing, any suggestions of improvements in my code is also very welcome, as I am new to this.


#2

Hello Dylan,
Before we go to code feedback, a recommendation for future posts: try to fit whole code in code tags. In your post the code is overlapping with comments which makes more difficult to read. Anyways i copied to R locally to track for issues.
I will be reviewing the code step by step and expanding this post with feedback.

1) CSS
You need to define only once and also add it into the head tag, therefore remove style from infoboxes:

output$body <- renderUI({
    tags$head(tags$style(type="text/css",".recalculating {opacity: 1.0;}"))
    div(width=12,
        # Info Boxes --------------------------------------------------------------
        fluidRow(box(height= 400, width=10, plotOutput("plot1", height=350)),
                 valueBoxOutput("activity1", width = 2)),
...
  })

2) Bracket before "if" redundant, although not an error per se
In output$activity you have wrapped if in () as:

(if(activity_level3 > 0.95 & activity_level3 < 1.05)
    ...
})

3) Consistency: output$activity(1 and 2) have na.omit line whilst other dont. This can lead to error where NA will be passed to if(). You can prevent this by adding na.rm = TRUE parameter to mean function instead of creating a copy of activity_level_math which will also have negligible performance advantage.

activity_level_math2 <-na.omit(activity_level_math2)

4) Logical concern: You are invalidating multiple render functions however you cannot control in which order they are executed whilst they are reading same files.
E.g. logfile1.txt is read by both plot1 and activity1 but you cannot 100% ensure they are going to read same output from accelerometer as it may be updated before the 2nd function is executed.
I'd suggest wrapping file access and output creation in observer which gets triggered by reactive timer.
read this with example provided on how it's done https://shiny.rstudio.com/reference/shiny/1.0.2/reactiveTimer.html

5) Reactive timer missing parameter:
as per function documentation (https://shiny.rstudio.com/reference/shiny/1.0.2/reactiveTimer.html)

A session object. This is needed to cancel any scheduled invalidations after a user has ended the session. If NULL, then this invalidation will not be tied to any session, and so it will still occur.

change your timer to:
autoInvalidate <- reactiveTimer(20, session = session)

6) File access locked?
Could it be that file access is refused to read.csv if accelerometer is writing to that particular file? This could explain the randomness of the error.
If I run this in R, guess what error is returned?

rfm = file(description = 'logfile.txt',open = 'w') #open file connection for writing
dat = read.csv(file = 'logfile.txt') #read csv of connection opened by another f()
Error in read.table(file = file, header = header, sep = sep, quote = quote,  : 
  no lines available in input

Rgds,
Peter