I am trying to create a way to track opening and closing of the breathing organ (i.e. a mouth) of several animals at the same time over the course of 45 minutes. The goal is to be able to calculate the total open time and frequency of opening for each animal. Basically, the idea is to have several stopwatches operating in parallel, while tracking two lists of values per animal: open time and close time.
The experiment would ideally go like this: I start the experiment and therefore the stopwatch. Every time animal 1 opens its breathing organ, I press open, and once it closes its breathing organ, I press close. The time of each, relative to the stopwatch started at the beginning of the experiment, are recorded in a dataframe for animal 1. This process repeats 10-15 times throughout 45 minutes. At the same time, another animal is opening and closing its breathing organ, and a separate dataframe for animal 2 is created using a different set of buttons. I would like to have this be possible for up to 10 animals simultaneously.
I have been able to make the stopwatches (example code below) using a watch
function, as well as include action buttons that output text corresponding to the difference in system time between start time of the experiment and time of pressing the open or close buttons. However, I am unsure of how to store these values in a dataframe for each animal.
I have looked around stackoverflow and found nothing that works, including this thread: r Shiny action button and data table output and this one: Add values to a reactive table in shiny
Let me know if you need any more info! Thanks in advance.
library(lubridate)
library(shiny)
library(DT)
# stopwatch function ----
stop_watch = function() {
start_time = stop_time = open_time = close_time = NULL
start = function() start_time <<- Sys.time()
stop = function() {
stop_time <<- Sys.time()
as.numeric(difftime(stop_time, start_time))
}
open = function() {
open_time <<- Sys.time()
as.numeric(difftime(open_time, start_time))
}
close = function() {
close_time <<- Sys.time()
as.numeric(difftime(close_time, start_time))
}
list(start=start, open=open, close=close, stop=stop)
}
watch = stop_watch()
# ui ----
ui <- fluidPage(
titlePanel("Lymnaea stopwatch"),
sidebarLayout(
sidebarPanel(
selectInput(
"select",
label = "Number of animals",
choices = c(1,2,3,4,5,6,7,8,9,10),
selected = c("1")
)
# action button conditionals ----
),
mainPanel(
h4("Start/Stop Experiment:"),
actionButton('start1',"Start"),
actionButton('stop1', "Stop"),
textOutput('initial1'),
textOutput('start1'),
textOutput('stop1'),
textOutput('stoptime1'),
conditionalPanel(
h4("Animal 1"),
condition = "input.select == '1'||input.select == '2'||input.select == '3'||input.select == '4'||input.select == '5'||input.select == '6'||input.select == '7'||input.select == '8'||input.select == '9'||input.select == '10'",
actionButton('open1', "Open"),
actionButton('close1', "Close"),
textOutput('open1'),
textOutput('opentime1'),
textOutput('close1'),
textOutput('closetime1'),
)
)
)
)
# server ----
server <- function(input, output, session) {
values <- reactiveValues()
values$df <- data.frame(colnames(c("Open", "Close")))
newEntry <- observe({
if(input$open1 > 0) {
newLine <- isolate(c(({watch$start()})))
isolate(values$df <- rbind(values$df, newLine))
}
})
output$table <- renderTable({values$df})
# n = 1 animal ----
observeEvent(input$start1, {
watch$start()
output$initial1 <- renderText(
"Timer started."
)
})
observeEvent(input$open1, {
watch$open()
output$open1 <- renderText(
"Time of opening:"
)
output$opentime1 <- renderText({
watch$open()
})
})
observeEvent(input$close1, {
watch$close()
output$close1 <- renderText({
"Time of closing:"
})
output$closetime1 <- renderText({
watch$close()
})
})
}
shinyApp(ui, server)