--- title: "Report on animal initial conditions and weekly weights" output: word_document params: data: ../../DATA/body_weights_measurement.xlsx --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = FALSE) ``` ```{r message = FALSE, warning = FALSE} # Load required packages library(readxl) library(tidyverse) library(ggbeeswarm) ``` ```{r} # Create some functions that are used in later code ## Function to read in mouse weights. This takes a filepath to an Excel sheet ## that follows the template of the animal weight collection template. It ## identifies all the sheets in that file and reads in all the ones that ## measure weekly weights. It returns one large dataframe with all of the ## measured weights. read_mouse_weights <- function(filepath) { # getting info about all excel sheets mouse_weights_sheets <- readxl::excel_sheets(filepath)[-1] # First sheet is initial data, not mouse weights mouse_weights <- purrr::map(mouse_weights_sheets, ~ readxl::read_excel(filepath, sheet = .x, col_types = c("text", # who_collected "text", # date_collected "text", # notch_id "numeric", # weight "text", # unit "text", # existing_cage_number "text", # new_cage_number "text", # group "text" # notes ))) %>% dplyr::bind_rows() %>% mutate(date_collected = lubridate::mdy(date_collected)) return(mouse_weights) } # Function to get the next cage number based on the # existing cage number and notch ID. If the mouse does not # switch cages again, the output is a vector of length 0. # This takes the dataframe and existing identifiers (notch id and # existing cage number) as inputs. It returns the next cage # that the mouse was moved to. If the mouse has not moved # from the existing case, the output has length 0. get_next_cage <- function(existing_cage_number, notch_id, df = our_mouse_weights){ next_cage <- df %>% filter(.data$existing_cage_number == {{existing_cage_number}} & .data$notch_id == {{notch_id}} & !is.na(.data$new_cage_number)) %>% pull(new_cage_number) return(next_cage) } # Function to get the full list of cages for each individual # mouse, over the course of all data collected to date. This # inputs the starting identifiers of the mouse (starting cage ID # and notch ID). It then works through any cage changes to create # a list for that mouse of all cages it was put in over the # course of the experiment. get_mouse_cages <- function(mouse_starting_cage, mouse_notch_id, df = our_mouse_weights){ mouse_cage_list <- mouse_starting_cage i <- 1 while(TRUE){ next_cage <- get_next_cage(existing_cage_number = mouse_cage_list[i], notch_id = mouse_notch_id, df = df) if(length(next_cage) == 0) { break } i <- i + 1 mouse_cage_list[i] <- next_cage } return(mouse_cage_list) } ``` ```{r} # Read in and process the data # Read in the mouse weights from the Excel template. This creates one large # dataframe with the weights from all the timepoints. our_mouse_weights <- read_mouse_weights(filepath = params$data) # Add a unique mouse ID for the first time point. This will become each mouse's # unique ID across all measured timepoints. our_mouse_weights <- our_mouse_weights %>% mutate(mouse_id = 1:n(), mouse_id = ifelse(date_collected == first(date_collected), mouse_id, NA)) # Create a dataframe that lists all mice at the first time point, # as well as a list of all the cages they have been in over the # experiment mice_cage_lists <- our_mouse_weights %>% filter(date_collected == first(date_collected)) %>% select(notch_id, existing_cage_number, mouse_id) %>% mutate(cage_list = map2(.x = existing_cage_number, .y = notch_id, .f = ~ get_mouse_cages(.x, .y, df = our_mouse_weights))) # Add a column with the latest cage to the weight dataframe our_mouse_weights$latest_cage <- NA # Loop through all the individual mice, based on mice with a # measurement at the first time point. Add the unique ID for # each mouse, which will apply throughout the experiment. Also # add the most recent cage ID, so the mouse can be identified # by lab members based on it's current location for(i in 1:nrow(mice_cage_lists)){ this_notch_id <- mice_cage_lists[i, ]$notch_id this_cage_list <- mice_cage_lists[i, ]$cage_list[[1]] this_unique_id <- mice_cage_lists[i, ]$mouse_id latest_cage <- this_cage_list[length(this_cage_list)] our_mouse_weights$mouse_id[our_mouse_weights$notch_id == this_notch_id & our_mouse_weights$existing_cage_number %in% this_cage_list] <- this_unique_id our_mouse_weights$latest_cage[our_mouse_weights$notch_id == this_notch_id & our_mouse_weights$existing_cage_number %in% this_cage_list] <- latest_cage } # Add a label for each mouse based on its notch_id and latest cage our_mouse_weights <- our_mouse_weights %>% mutate(mouse_label = paste("Cage:", latest_cage, "Notch:", notch_id)) # Read in the data from the original file with the initial animal # characteristics mouse_initial <- readxl::read_excel(params$data, sheet = 1, col_types = c("text", # notch_id "text", # starting_cage_number "text", # dob "text", # species "text", # sex "text" # group )) %>% mutate(dob = lubridate::mdy(dob), sex = forcats::as_factor(sex)) # Figure out the starting cage for each mouse, so they can be incorporated # with the initial data so we can get the mouse ID that was added for the # starting time point mouse_ids <- our_mouse_weights %>% filter(date_collected == first(date_collected)) %>% select(notch_id, existing_cage_number, mouse_id) %>% rename(starting_cage_number = existing_cage_number) # Merge in the mouse IDs with the dataframe of initial mouse characteristics mouse_initial <- mouse_initial %>% left_join(mouse_ids, by = c("notch_id", "starting_cage_number")) # Join the initial data with the weekly weights data into one large dataset our_mouse_weights <- our_mouse_weights %>% left_join(mouse_initial, by = c("mouse_id", "notch_id", "group")) ``` # Summary of experimental animals This section gives some information on the experimental animals both at the start of the experiment and over the course of the experiment. ```{r} # Create a table that summarizes the animals at the start of the experiment mouse_initial %>% summarize(Species = paste(unique(species), collapse = ", "), `Total animals` = n(), `Sex distribution` = paste0("male: ", sum(sex == "m"), ", female: ", sum(sex == "f")), `Experimental groups` = paste(unique(group), collapse = ", "), `N. of starting cages` = length(unique(starting_cage_number))) %>% mutate_all(as.character) %>% pivot_longer(everything()) %>% mutate(name = paste0(name, ":")) %>% knitr::kable(col.names = c("", ""), caption = "Summary of experimental animals at the start of the experiment", align = c("r", "l")) ``` \newpage # Animal weights This section provides summaries of mouse weights over the course of the experiment. ```{r} # Create a plot of mouse weights over time our_mouse_weights %>% ggplot(aes(x = date_collected, y = weight, group = mouse_id, color = sex)) + geom_line() + facet_wrap(~ group) + ggtitle("Animal weights over time by experiment group") + labs(x = "Date collected", y = "Weight (g)") ``` \newpage ```{r} # Plot animal weight boxplots for the latest time point our_mouse_weights %>% filter(date_collected == last(date_collected)) %>% ggplot(aes(x = group, y = weight)) + geom_beeswarm(aes(color = sex)) + geom_boxplot(fill = NA, color = "dodgerblue") + ggtitle("Animal weights at last collection by experimental group") + labs(x = "Experimental group", y = "Weight (g)") ``` \newpage ```{r} # Plot animal weights by animal handler our_mouse_weights %>% ggplot(aes(x = date_collected, y = weight, color = who_collected)) + geom_point() + ggtitle("Animal weights by animal handler") + labs(x = "Date collected", y = "Weight (g)", color = "Person who\nhandled the\nanimal") ``` \newpage ```{r} # Create table of animal weight changes since previous time point our_mouse_weights %>% select(date_collected, weight, group, mouse_label, sex) %>% group_by(mouse_label) %>% mutate(weight_change = (weight - lag(weight)) / lag(weight)) %>% ungroup() %>% filter(date_collected == last(date_collected)) %>% mutate(formatted_weight_change = paste0(formatC(weight_change * 100, digits = 1, format = "f"), "%")) %>% arrange(weight_change) %>% select(mouse_label, group, sex, weight, formatted_weight_change) %>% knitr::kable(col.names = c("Mouse", "Experimental group", "Sex", "Weight (g)", "Weight change since last measure"), caption = "Individual data on weight changes in mice between current measurement and previous measurement.") ``` ```{r} # Write out processed data into a CSV file write_csv(our_mouse_weights, "mouse_weights_output.csv") ```