library(growthrates) # fit_growthmodel(): Calcular la tasa de crecimiento a partir de datos de microplacas.
library(lmerTest) # Pruebas estadisticas
# Paquetes adicionales (no los mencionan pero son necesarios)
library(readxl) # lectura de archivos de excel
library(tidyverse) # Manipulacion de datos
library(reshape2) # melt(): reduccion de datos
library(ggh4x) # paquete que extiende las funcionalidades de facet_wrap y facet_grid
library(RColorBrewer) # Paquete para asignar paleta de colores
Figura 1
Análisis de genomas bacterianos evolucionados en ausencia de fagos
NOTA: Agregar el diagrama con descripcion del analisis.
Figure 1B. La resistencia es costosa
Paquetes
NOTA: La funcion
fit_growthmodel()
, toma los datos de la siguiente forma: cada fila es la medida de un único pocillo en un único punto temporal, con columnas adicionales «Tratamiento» y «DO». Se ajusta una curva logística a cada pocillo por separado utilizando la DO a lo largo del tiempo. He utilizado los siguientes parámetros: lower=c(y0=0.000001,mumax=0,K=0),upper=c(y0=0.05,mumax=5,K=1.5)),p=c(y0=0.01,mumax=0.2,K=0.1)
GC_long_to_growthrates() function
#' @title Calcular tasas de crecimiento
#' @description
#' Esta función procesa los datos de crecimiento de un experimento en múltiples pozos, ajusta un modelo logístico de
#' crecimiento para cada pozo, y extrae la tasa de crecimiento r.
#' @author Reena Debray
#'
#' @param GC_long # Un data frame en formato largo que contiene los datos de crecimiento.
#' @param lower # Un vector de límites inferiores para los parámetros del modelo de crecimiento.
#' @param upper # Un vector de límites superiores para los parámetros del modelo de crecimiento.
#' @param p # Un vector de parámetros iniciales para el ajuste del modelo.
#'
#' @return # El resultado es un data frame con las tasas de crecimiento para cada combinación de pozo y tratamiento.
#' \item{well}{The identifier of the well.}
#' \item{treatment}{The treatment associated with the well.}
#' \item{r}{The growth rate obtained from the fitted logistic model.}
#'
#' @import growthrates
#' @import lmerTest
#'
#' @export
#'
#' @examples
#' # Example data
#' GC_long <- data.frame(
#' Well = rep(c("A1", "A2"), each = 10),
#' Time = rep(1:10, 2),
#' OD = runif(20),
#' Treatment = rep(c("Control", "Treatment"), each = 10)
#' )
#'
#' # Parameters for the logistic model
#' lower <- c(y0 = 0.000001, mumax = 0, K = 0)
#' upper <- c(y0 = 0.05, mumax = 5, K = 1.5)
#' p <- c(y0 = 0.01, mumax = 0.2, K = 0.1)
#'
#' # Calculate growth rates
#' growth_rates <- GC_long_to_growthrates(GC_long, lower, upper, p)
#' print(growth_rates)
<- function(GC_long, lower, upper, p){
GC_long_to_growthrates ### initialize data frame / Iniciar dataframe
# Objeto donde se almacenarán las tasas de crecimiento calculadas
<-data.frame(matrix(nrow=0, ncol=3))
growthrates# Populate with model fit / Rellenar con el ajuste del modelo
# Argumentos:
# `treatment`: Para cada pozo, se extrae el tratamiento asociado a partir de la columna Treatment.
# Modelo de crecimiento: Se ajusta un modelo de crecimiento logístico (especificado por `grow_logistic`) a los datos de tiempo (`Time`)
# y densidad óptica (`OD`) para el pozo actual.
# `r`: Se extrae el coeficiente de crecimiento (r) del modelo ajustado usando coef, y se convierte a un número con as.numeric.
# Agregar a growthrates: Se añade una nueva fila al data frame growthrates que contiene el pozo (well),
# el tratamiento (treatment) y la tasa de crecimiento (r).
for (well in unique(GC_long$Well)){
<- GC_long[GC_long$Well == well,"Treatment"][1]
treatment <- as.numeric(coef(fit_growthmodel(FUN = grow_logistic, GC_long[GC_long$Well==well,"Time"], GC_long[GC_long$Well==well,"OD"],p=p,lower=lower,upper=upper))[2])
r # Cambiar formato a numerico
<- rbind(growthrates,c(well,treatment,r))
growthrates
}### Return output
colnames(growthrates)=c("well","treatment","r")
$r <- as.numeric(growthrates$r)
growthratesreturn(growthrates)
}
Cargar datos
Cargar informacion de “Costs_of_Res.xlsx” como variable costs_of_res
.
<- read_excel("data/Costs_of_Res.xlsx") costs_of_res
Resistencia del fago y la disposición de la placa
Calcular los valores ajustados controlando la resistencia del fago y la disposición de la placa. Expresar los valores ajustados como porcentaje de la aptitud de tipo wild-type.
$fitted <- fitted.values(lm(r~(Population=="ancDC3000") + Column + Plate,costs_of_res))
costs_of_res$fitted_percWT <- costs_of_res$fitted/mean(unlist(costs_of_res[costs_of_res$Population=="ancDC3000","fitted"]))*100 costs_of_res
Reordenar los aislados por gen de resistencia y tasa de crecimiento.
<-costs_of_res[order(costs_of_res$Gene,-costs_of_res$r),] costs_of_res
Coloque el aislado sin diferencias genéticas detectadas en la parte derecha del gráfico.
$Population=="MS15","Gene"] <- "Z"
costs_of_res[costs_of_res$Population=="MS15","Annotation"] <- "Z"
costs_of_res[costs_of_res$order<-seq(1,nrow(costs_of_res)) costs_of_res
Las bacterias resistentes crecen más despacio que sus antepasadas sensibles
<-costs_of_res[costs_of_res$Population!="ancDC3000",]
costs_of_res_R<-aggregate(costs_of_res_R$fitted_percWT,by=list(costs_of_res_R$Population,costs_of_res_R$Gene),FUN=mean)
costs_aggcolnames(costs_agg)<-c("Population","Gene","fitted_percWT")
t.test(x = costs_agg$fitted_percWT,mu = 100,alternative = "less")
One Sample t-test
data: costs_agg$fitted_percWT
t = -8.4049, df = 21, p-value = 1.849e-08
alternative hypothesis: true mean is less than 100
95 percent confidence interval:
-Inf 91.98815
sample estimates:
mean of x
89.92562
# La variación en las tasas de crecimiento no se explica por el gen de resistencia (excluir la población sin mutaciones detectadas)
anova(lm(fitted_percWT~Gene,costs_agg[costs_agg$Population!="MS15",]))
Analysis of Variance Table
Response: fitted_percWT
Df Sum Sq Mean Sq F value Pr(>F)
Gene 3 65.56 21.854 0.6731 0.5802
Residuals 17 551.95 32.468
Salvar la variable
Pordemos salvar la variable para la figura 2.
save(costs_agg, file = "data/costs_agg.RData")
Grafica
Tasas de crecimiento de la población de cepas resistentes en ausencia de fago, basadas en un modelo logístico ajustado a una curva de crecimiento de 40 h (n = 22 cepas).
# Asignar colores a los titulos de los facets
<- strip_themed(text_x = elem_list_text(color = brewer.pal(5, "Dark2")))
strip
# Guardar las etiquetas que van en los títulos de los facets
<- distinct(costs_of_res[,c("Gene","Annotation")])[-c(1:2),] %>%
strip_label mutate(Annotation = str_replace(Annotation, "_","\n"),label = paste(Gene,Annotation, sep = "\n"))
# Crear la figura
$Population!="ancDC3000",] %>% # El siguiente paso quita las Z que asignamos antes y más bien asigna el orden utilizando niveles en el factor de label
costs_of_res[costs_of_resmutate(Population = ifelse(Population == "MS15","no detected\nmutation",Population),
Gene = ifelse(Gene == "Z","",Gene),
Annotation = ifelse(Annotation == "Z","",Annotation),
Annotation = str_replace(Annotation, "_","\n"),
label = paste(Gene,Annotation, sep = "\n")) %>%
mutate(label = factor(label, levels = c(strip_label$label,"\n"))) %>%
ggplot()+
stat_summary(aes(x = reorder(Population,-fitted_percWT),
y = fitted_percWT,
group=Population,
fill=Gene),
geom="pointrange",
shape=21,
size=0.8)+
geom_hline(yintercept=100,linetype="dashed")+
scale_fill_brewer(palette="Dark2")+
guides(fill=F)+
ylab("Fitness (% of wild-type)")+
facet_wrap2(~label,
scales="free_x",
#space="free_x",
strip.position = "bottom",
nrow = 1,
strip = strip
+
)theme_classic(base_size=18)+
theme(axis.title.x=element_blank(),
axis.text.x=element_text(angle = 90),
#axis.ticks.x=element_blank(),
strip.background = element_blank(),
strip.placement = "outside",
strip.text = element_text(size = 12))