R Shiny: View the logfile and update it with new entries - r

I am new to R and certainly very new to RShiny.
I wrote a packages which logs events into a log file. Rstudio is capable of viewing live logging unitl the file is 5MB. So now i am thinking about writing a Rshiny app that views the logs as they are being written to the file.
Which functions would help me to update the viewer?
Thanks!

You can call invalidateLater inside a reactive when you import the data. Data will be refreshed every time invalidateLater will fire (in my case every second).
Here a really silly example (my .csv doesn't update, it just prints that data is being refreshed to console):
library(shiny)
ui <- fluidPage(
tableOutput("data")
)
server <- function(input, output, session) {
# mtcars.csv will be read every second
mtcars_df <- reactive({
invalidateLater(1000, session)
read.csv("mtcars.csv")
})
# mtcars_df is a reactive, hence will force the table to re-render
output$data <- renderTable({
print(paste("Table refreshed at", Sys.time(), collapse = " "))
mtcars_df()
})
}
shinyApp(ui, server)

Related

Shiny - How to test fileInput()

I'm trying to write tests in order to check if a shiny function fileInput() is reading files correctly.
My problem is that I don't know what to write in session$setInputs() in order to grab the file from my system.
Here is an example app:
library(shiny)
ui <- fluidPage(
tagList(
fileInput("file", "Please upload a file"),
tableOutput("text")
)
)
server <- function(input, output, session){
file <- reactive({input$file})
output$text <- renderTable({
req(file())
read.csv(file()$datapath)
})
}
shinyApp(ui, server)
Now, I want to be able to use testServer() in order to set a file address and see if my app loads it correctly, but I can't figure out how to do it:
address <- "path/to/text.csv"
testServer(server, {
session$setInputs(file = address)
print(file())
})
I think it has to do with the fact that fileInput() uploads the file to a temp folder and returns to shiny a dataframe where you can get the datapath, but I'm unable to simulate this pass in order to make the test work
I have the same question as you do, I did some investigating and could not find any way of testing fileInput with testServer or testthat. The best solution that I found was testing fileInput by taking a snapshot when recording a test with recordTest() of the shinytest package.
Sorry for answering this late.
I asked the same question at rstudio's forums and got an answer here
The basics of it are setting the file's datapath as a list:
address <- "path/to/text.csv"
testServer(server, { session$setInputs(file= list(datapath = address)) })

Shiny: Source file to refresh data with observe

I have a helper.R, which I want to source from app.R to refresh data. helper.R has path variables based on Sys.Date(), like
data_path <- paste0("data_", Sys.Date(), ".csv")
I have a shiny application running on a shiny server and I want to source helper.R everyday using observe
helper.R
cur_date <- Sys.Date()
app.R
observe({
invalidateLater(10000, session)
if (Sys.Date() > cur_date) {
source("helper.R")
}
})
For some reason this setup is not working for data refresh. I am not much familiar with scope of variables in R. Any help is appreciated.

Refresh checkboxinput control

I have a check box control defined in my UI which is reading excel files from a directory and displaying for loading. User selects the file and there is a function defined which loads its data into data frame.
Issue i am facing is that once application starts any addition/deletion of files in the directory is not reflected into checkbox i.e. files read at the start of application are always displayed.
Kindly share any solution.
Regards
Here is one possible option. We use invalidateLater(1000) to invalidate the observer every second, and we use a reactiveVal to keep track of the files currently as choices in the selectInput, so we only re-render the input if the files have changed. Hope this helps!
library(shiny)
ui <- fluidPage(
selectInput('input1','Files: ', NULL)
)
server <- function(input,output, session)
{
# To keep track of current files
prev.files<-reactiveVal(NULL)
observe({
invalidateLater(1000)
isolate({
new_files <- list.files()
# If files have changed...
if(!isTRUE(all.equal(new_files,prev.files())))
{
print('Updating selectInput')
updateSelectInput(session,'input1',choices=new_files) # update selectInput
prev.files(new_files) # Update prev.files()
}
})
})
}
shinyApp(ui,server)

Shiny Application to check something at a specified time

I was wondering if there was a way to get Shiny to check something at a specified time each day if it is running. Now I know this is not recommended and I have read through
Schedule task on a shiny application
Schedule R script using cron
call myFunction daily, at specific time, in shiny?
as well as I am aware of the reactiveTimer function in Shiny. However, I have developed and deployed my Shiny App as a desktop app instead of a url and consequently my colleagues like to leave it open. Here is the basic example of what I am trying to:
library(shiny)
ui <- fluidPage()
server <- function(input, output, session) {
test <- reactiveValues(value = format(as.POSIXlt(Sys.time()), "%H:%M"))
observeEvent(test$value == "7:15", {
stopApp()
})
}
shinyApp(ui, server)
The reason I would like the application to stop at a scheduled time is because I want the application to check for an update and re-launch after it updates. I suppose it should only stop if their is something to update but the above is a simpler idea of what I am trying to accomplish.
Is there anyway to get shiny to execute some code at a specific time? I know reactiveTimer is an option but this performs a task after a specified amount of time but not at a specific time each day.
Another option is if I could get a vbs script or even just a different r script to close the Shiny App but I have not been able to figure out how to do that either. Any advice or ideas would be a big help. Thanks!
This does the trick (a little verbose, but works)
You need to set the variable timeStop (HH:MM:SS)
library(shiny)
ui <- fluidPage(
uiOutput("info")
)
server <- function(input, output, session) {
## Variable to set the time when app stops automatically (HH:MM:SS)
timeStop <- "22:47:20"
toStop <- as.POSIXct(timeStop, format="%H:%M:%S")
if (Sys.time() > toStop) {
toStop <- toStop + 86400
}
secsToStop <- round(as.numeric(difftime(toStop, Sys.time(), units = "secs")) * 1000)
timeToStop <- reactiveTimer(secsToStop)
trick <- reactiveValues()
trick$toFire <- FALSE
observeEvent(timeToStop(), {
if (trick$toFire) {
stopApp()
} else {
trick$toFire <- TRUE
}
})
output$info <- renderUI({
h2(paste("App will stop automatically at ", toStop))
})
}
shinyApp(ui, server)

writing wav-file in shiny app with seewave and tuneR

I have a shiny app with a number of tabPanels.
In one of these panels I want to write a time signal generated in seewave and tuneR to a www subdirectory.
If I run the commands on the R-promt, everything works, but I can't get it running in my server.R.
I tried observe, but then the input$ variables are not updated:
observeEvent(input$button,{
cat("Writing wav file")
})
eventReactive(input$button,{
"Inbutton"
pi<-4*atan(1)
s5<-synth(44100,5,input$freq1,input$amp1*2000,"sine",shape=NULL,p=0,
am=c(0,0,0),fm=c(0,0,0),harmonics=1,plot=FALSE,output="Wave")
s6<-synth(44100,5,input$freq2,input$amp2*2000,"sine",shape=NULL,
p=input$phase/180*pi,am=c(0,0,0),fm=c(0,0,0),
harmonics=1,plot=FALSE,output="Wave")
s7<-s5+s6
str(s7)
Wobj<-s7
wav_dir<-"./www"
wav_file<-file.path(wav_dir,"howling2.wav")
writeWave(Wobj,filename=wav_file)
play(s7)
})
I've managed somehow to save the file. I defined function that generates the sound and load it beforehand. Then in server function I call it like that:
server <- function(input, output){
observeEvent(input$button, {
sound <- sonify(input$name) # this is already a Wave object
wvname <- paste0("sound", input$button,".wav")
writeWave(sound, paste0("www/", wvname))
})
}
Then to implement it in UI follow this and this

Resources