matiasandina / fed3

An R package to read and analyze data from FED3 devices
https://matiasandina.github.io/fed3/
Other
0 stars 0 forks source link

Add `count_stage()` function #9

Open matiasandina opened 1 year ago

matiasandina commented 1 year ago

When doing experiments. We often want to count fast the number of events to do the classic pre-stim-post plot.

Here's a preliminary idea of how to do that

count_stage <- function(data, time_col){
  # This is difficult to make it variable for all people
  # Stimulation/treatment protocols might be hard to integrate without
  # many arguments
  # if time_col is numeric, units might be a problem
  # if time_col is datetime, many more problems
  stages <- factor(c("Pre", "Stim", "Post"), 
                   levels = c("Pre", "Stim", "Post"))
  stim_start_sec <- 30 * 60
  stim_end_sec <- 30 * 2 * 60
  # This includes ALL events, not just pellets!

   time_var_enquo <- rlang::enquo(time_col)
   time_var_name <- rlang::quo_name(time_var_enquo)
   if (isFALSE(time_var_name %in% names(data))) {
     time_col <- NA
   }
  data %>% 
    mutate(stage = case_when({{time_col}} < stim_start_sec ~ "Pre",
                   between({{time_col}}, stim_start_sec, stim_end_sec) ~ "Stim",
                   {{time_col}} > stim_end_sec ~ "Post",
                   TRUE ~  NA)) %>% 
  mutate(stage = factor(stage, levels = levels(stages))) %>% 
  count(stage, .drop = FALSE)
}

A nice property is that it can handle empty data frames like this

count_stage(data.frame(), NA)
  stage n
1   Pre 0
2  Stim 0
3  Post 0
matiasandina commented 1 year ago

In the past, this function was split in two. One that adds the stage, and one that counts. It is somewhat related to #11, which needs to add stages using start_dt and end_dt for treatments. In the case of #11, it's because of alignment, but a general purpose function that adds labels to the data might be a good idea. It's tough to handle the unique cases without asking a lot from the user (properly and manually defining each start_dt and end_dt for the data to be assigned to epoch by id).

add_epoc <- function(joint_pellet_data, experiment_epocs){
  joint_pellet_data %>% 
    mutate(
      epoc = case_when(
        data.table::between(tdt_datetime, 
                            exp_start, 
                            experiment_epocs["opto_start"]) ~ "pre",
        data.table::between(tdt_datetime, 
                            experiment_epocs["opto_start"], 
                            experiment_epocs["opto_stop"]) ~ "stim",
        data.table::between(tdt_datetime, 
                            experiment_epocs["opto_stop"], 
                            exp_stop) ~ "post",
        TRUE ~ "hab"),
      epoc = factor(epoc,  levels=c("pre", "stim", "post")))  
}

summarise_by_epoc <- function(df){
  df %>% 
    group_by(epoc, .drop=F) %>% 
    count()  
}