in a shiny app I got built in an invalidation condition for time cycle of one day (86400000 millisecs = 24 hours). Worked fine till a system restart and instalation of new R version 3.2.4. Now it doesn`t work properly. What i mean is the invalidation intervals do not match and after some time the process seems to expire.
I tried to test it with 30 sec interval:
invalidateLater(30000, session)
Using a cat function I can track when was the refresh of the reactive object innitiated:
MyData <- reactive({ # Responds to changes. But in here, only the invalidation triggers change.
invalidateLater(30000, session) # Invalidates MyData() after 30000 millisecs = 30 secs.
connection <- odbcConnect(dns, usr, pass)
SituationToday<-{cat(Sys.time());sqlQuery(connection, "SELECT ALL * FROM Table;")}
odbcClose(connection)
SituationToday
})
The triggers outcome from the cat function is in UNIX format:
val<-c(1458036067,1458036158,1458036251,1458036340,1458036430,1458036519,1458036608,1458036700)
The time differences between the individual time points are not what I expected:
diff(as.POSIXct(val, origin="1970-01-01"))
Time differences in mins:
[1] 1.516667 1.550000 1.483333 1.500000 1.483333 1.483333 1.533333
That´s far from 30 sec interval as desired. Moreover, that´s all I get, the invalidation process stops after 11 mins aproximately (UNIX time value 458036700).
I use shiny v. 0.13.1,
shinydashbaord 0.5.1,
R 3.2.4, Windows Server2012R2.
Anyone has an idea what can be the cause of this behaviour?
Related
I want the running shiny application to update the data at the specified time, every time the minutes in the system are multiples of 15 (for example: 12:00, 12:15, 12:30, 12:45, 13:00, 13:15 etc). I currently use a reactive timer that fires every 15 minutes, but that doesn't solve my problem. How can I update the application only at the moment when the system time becomes a multiple of 15?
Get the current time, determine the amount of time until the next refresh, and call invalidateLater() appropriately.
For instance, the following shiny app refreshes the clock on each multiple of 15 seconds:
library(shiny)
ui <- fluidPage(
mainPanel(
textOutput('time')
)
)
server <- function(input, output) {
output$time <- renderText({
time <- as.integer(format(Sys.time(), "%S"))
invalidateLater((15 - time %% 15) * 1000)
format(Sys.time(), "%H:%M:%S")
})
}
shinyApp(ui = ui, server = server)
EDIT:
I have simplified slightly the computation since the last edit. time <- as.integer(format(Sys.time(), "%S")) simply gets the second-part of current time. We compute this amount of seconds MODULO 15 (time %% 15) to obtain the number of seconds after last 15s multiple. We then subtract that value from 15 to obtain the number of seconds until the next multiple. Since the time must be in milliseconds, we multiply the result by 1000.
I've been trying to find the computational expense with Sys.time(), starting with some simple operations.
I started with something like this
a=c(10,6,8,3,2,7,9,11,13)
t_beginning=Sys.time()
cl2=NULL
indx=which(a==7)
t_ending=Sys.time()
print(t_ending-t_beginning)
and it gives me about 0.0023sec after running the code in Rstudio.
Then the code is put into a for loop to find the average expense of the two lines.
sum=0
a=c(10,6,8,3,2,7,9,11,13)
for (i in 1:5) {
print(i)
t_beginning=Sys.time()
cl2=NULL
indx=which(a==7)
t_ending=Sys.time()
sum=t_ending-t_beginning+sum
print(t_ending-t_beginning)
}
sum/5
It turns out that, for every iteration in the for loop, the time consumption is just several milliseconds, much less than what it took as out of the for loop.
[1] 1
Time difference of 7.152557e-06 secs
[1] 2
Time difference of 5.00679e-06 secs
[1] 3
Time difference of 4.053116e-06 secs
[1] 4
Time difference of 4.053116e-06 secs
[1] 5
Time difference of 5.00679e-06 secs
I expect that the average time cost of the for loop to be about the same as that without a loop, but they are so different. Not sure why this is happening. Can anyone reproduce the same? Thanks!
The difference comes from the way RStudio (or R) runs the code.
The original code is executed line by line, so the timing you get includes interface between RStudio and R.
a=c(10,6,8,3,2,7,9,11,13)
t_beginning=Sys.time()
cl2=NULL
indx=which(a==7)
t_ending=Sys.time()
print(t_ending-t_beginning)
# Time difference of 0.02099395 secs
If, however, you run all this code at once, by wrapping the code in curvy brackets, the timing you get improve drastically:
{
a=c(10,6,8,3,2,7,9,11,13)
t_beginning=Sys.time()
cl2=NULL
indx=which(a==7)
t_ending=Sys.time()
print(t_ending-t_beginning)
}
# Time difference of 0 secs
I am maybe misusing R a little, but I wish to execute R commands et specific times after my script started. The time when the commands should be executed is saved in a data frame.
e.g.
Time <- c(0.5, 5, 13, 30)
Text <- c("Half a second", "5 seconds", "13 seconds", "Half a minute")
df <- data.frame(Time = Time, Text = Text)
df
# Time Text
#1 0.5 Half a second
#2 5.0 5 seconds
#3 13.0 13 seconds
#4 30.0 Half a minute
The aim is to execute a command eg. print() after x Millisecond (stored in df$Time_ms) since the program start has past.
My first approach would be just to use Sys.sleep() between the commands. This would be almost acceptable, but since each command also takes some time (print() not really but others more) it will not be super accurate.
My best solution is to use 'while' loops:
# Programm start
start_time <- Sys.time() # Save Program start time.
for(i in 1:nrow(df)){
while(Sys.time() < df$Time[i] + start_time){} # Wait until the System Time is larger than start time plus the time when the command shall be executed.
print(paste(df$Text[i], "has passed.")) # Execute the command.
}
It is working. But I am not that experienced with programming, but I guess it is not a very elegant solution. What do you think? Does someone have a "nicer" solution?
I ended up using the proposal from nicola, with a minor change. If the program runs already for more than a minute and you subtract the 'start_time' current time 'Sys.time()' the result will be in minutes and not in second anymore. To prevent this, I use 'difftime'.
# Create example data.frame
Time <- c(0.5, 5, 13, 30)
Text <- c("Half a second", "5 seconds", "13 seconds", "Half a minute")
df <- data.frame(Time = Time, Text = Text)
# Programm start
start_time <- Sys.time() # Save Program start time.
for(i in 1:nrow(df)){
wait <- df$Time[i]-(as.numeric(difftime(Sys.time(),start_time, units = "secs"))) # Calculate the waiting time in second.
Sys.sleep(wait)
print(paste(df$Text[i], "has passed.")) # Execute the command.
}
I want to run a R code at a specific time that I need.
And after the process finished, I want to terminate the R session.
If a code is as below,
tm<-Sys.time()
write.table(tm,file='OUT.TXT', sep='\t');
quit(save = "no")
What should I do to run this code at "2012-04-18 17:25:40".
I need your help. Thanks in advance.
It is easiest to use the Task Scheduler of Windows, or a cron job under Linux. There you can specify a command or program that should be run at a certain time you specify.
If somehow you cannot use the cron job service and have to schedule within R, the following R code shows how to wait a specific amount of time so as to execute at a pre-specified target time.
stop.date.time.1 <- as.POSIXct("2012-12-20 13:45:00 EST") # time of last afternoon execution.
stop.date.time.2 <- as.POSIXct("2012-12-20 7:45:00 EST") # time of last morning execution.
NOW <- Sys.time() # the current time
lapse.time <- 24 * 60 * 60 # A day's worth of time in Seconds
all.exec.times.1 <- seq(stop.date.time.1, NOW, -lapse.time) # all of afternoon execution times.
all.exec.times.2 <- seq(stop.date.time.2, NOW, -lapse.time) # all of morning execution times.
all.exec.times <- sort(c(all.exec.times.1, all.exec.times.2)) # combine all times and sort from recent to future
cat("To execute your code at the following times:\n"); print(all.exec.times)
for (i in seq(length(all.exec.times))) { # for each target time in the sequence
## How long do I have to wait for the next execution from Now.
wait.time <- difftime(Sys.time(), all.exec.times[i], units="secs") # calc difference in seconds.
cat("Waiting for", wait.time, "seconds before next execution\n")
if (wait.time > 0) {
Sys.sleep(wait.time) # Wait from Now until the target time arrives (for "wait.time" seconds)
{
## Put your execution code or function call here
}
}
}
I want to run a R code at a specific time that I need.
And after the process finished, I want to terminate the R session.
If a code is as below,
tm<-Sys.time()
write.table(tm,file='OUT.TXT', sep='\t');
quit(save = "no")
What should I do to run this code at "2012-04-18 17:25:40".
I need your help. Thanks in advance.
It is easiest to use the Task Scheduler of Windows, or a cron job under Linux. There you can specify a command or program that should be run at a certain time you specify.
If somehow you cannot use the cron job service and have to schedule within R, the following R code shows how to wait a specific amount of time so as to execute at a pre-specified target time.
stop.date.time.1 <- as.POSIXct("2012-12-20 13:45:00 EST") # time of last afternoon execution.
stop.date.time.2 <- as.POSIXct("2012-12-20 7:45:00 EST") # time of last morning execution.
NOW <- Sys.time() # the current time
lapse.time <- 24 * 60 * 60 # A day's worth of time in Seconds
all.exec.times.1 <- seq(stop.date.time.1, NOW, -lapse.time) # all of afternoon execution times.
all.exec.times.2 <- seq(stop.date.time.2, NOW, -lapse.time) # all of morning execution times.
all.exec.times <- sort(c(all.exec.times.1, all.exec.times.2)) # combine all times and sort from recent to future
cat("To execute your code at the following times:\n"); print(all.exec.times)
for (i in seq(length(all.exec.times))) { # for each target time in the sequence
## How long do I have to wait for the next execution from Now.
wait.time <- difftime(Sys.time(), all.exec.times[i], units="secs") # calc difference in seconds.
cat("Waiting for", wait.time, "seconds before next execution\n")
if (wait.time > 0) {
Sys.sleep(wait.time) # Wait from Now until the target time arrives (for "wait.time" seconds)
{
## Put your execution code or function call here
}
}
}