library(ggplot2)
library(tidyr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Create dataframe
data <- data.frame(
  Week = 0:5,
  Plasmid_Free = c(32, 128, 128, 128, 128, 256),
  Plasmid_Carrying = c(64, 64, 128, 128, 256, 256)
)

# Convert to long format for ggplot
data_long <- data %>%
  pivot_longer(cols = c(Plasmid_Free, Plasmid_Carrying),
               names_to = "Condition",
               values_to = "IC90")




p1 <- ggplot(data_long, aes(x = Week, y = IC90, color = Condition)) +
  geom_line(size = 1.2) +
  geom_point(size = 3) +
  scale_color_manual(values = c("Plasmid_Free" = "aquamarine4",
                                "Plasmid_Carrying" = "violetred1")) +
  
  labs(
    title = "Trajectory of Biofilm Antibiotic Tolerance",
    subtitle = "Effects of Plasmid Carriage",
    x = "",
    y = "IC90 Kanamycin (µg/ml) "
  ) +
  
  theme_minimal(base_size = 14) +
  theme(legend.position = "none") +
  
  # Give space for labels on right
  expand_limits(x = max(data_long$Week) + 0.5) +
  
  annotate("text", x = 2, y = 175,
           label = "Plasmid Carrying",
           color = "violetred1", size = 5) +
  
  annotate("text", x = 5, y = 150,
           label = "Plasmid Free",
           color = "aquamarine4", size = 5)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
p1
data_norm <- data_long %>%
  dplyr::group_by(Condition) %>%
  dplyr::mutate(Fold_Change = IC90 / IC90[Week == 0])

p2 <- ggplot(data_norm, aes(x = Week, y = Fold_Change, color = Condition)) +
  geom_line(size = 1.2, linetype = "dashed") +
  geom_point(size = 3) +
  scale_color_manual(values = c("Plasmid_Free" = "aquamarine4",
                                "Plasmid_Carrying" = "violetred1")) +
  labs(
    title = "",
    x = "Week",
    y = "Log Fold Change",
    color = ""
  ) +
  theme_minimal(base_size = 14) +
    # Give space for labels on right
  expand_limits(x = max(data_long$Week) + 0.5) +
  
  annotate("text", x = 2.75, y = 1.5,
           label = "Plasmid Carrying",
           color = "violetred1", size = 5) +
  
  annotate("text", x = 2, y = 4.7,
           label = "Plasmid Free",
           color = "aquamarine4", size = 5) +
    theme(legend.position = "none") 

p2
library(patchwork)


combined_plot <- p1 / p2

combined_plot
combined_plot

Create the dtaframe for OD590 across timepoints

biofilm <- tribble(
  ~Week, ~Population, ~Biological_Replicate, ~Technical_Replicate, ~OD590,
  0, "Plasmid-Free", 1, 1, 0.2548,
  0, "Plasmid-Free", 1, 2, 0.1868,
  0, "Plasmid-Free", 1, 3, 0.2458,
  0, "Plasmid-Free", 1, 4, 0.3248,
  0, "Plasmid-Free", 1, 5, 0.4168,
  0, "Plasmid-Free", 1, 6, 0.4228,
  0, "Plasmid-Free", 2, 1, 0.3768,
  0, "Plasmid-Free", 2, 2, 0.3618,
  0, "Plasmid-Free", 2, 3, 0.3938,
  0, "Plasmid-Free", 2, 4, 0.4498,
  0, "Plasmid-Free", 2, 5, 0.4728,
  0, "Plasmid-Free", 2, 6, 0.4728,
  0, "Plasmid-Free", 3, 1, 0.2028,
  0, "Plasmid-Free", 3, 2, 0.2598,
  0, "Plasmid-Free", 3, 3, 0.3638,
  0, "Plasmid-Free", 3, 4, 0.2988,
  0, "Plasmid-Free", 3, 5, 0.3998,
  0, "Plasmid-Free", 3, 6, 0.8288,
  0, "Plasmid-Carrying", 1, 1, 0.0638,
  0, "Plasmid-Carrying", 1, 2, 0.0738,
  0, "Plasmid-Carrying", 1, 3, 0.1028,
  0, "Plasmid-Carrying", 1, 4, 0.0738,
  0, "Plasmid-Carrying", 1, 5, 0.0548,
  0, "Plasmid-Carrying", 1, 6, 0.0668,
  0, "Plasmid-Carrying", 2, 1, 0.6158,
  0, "Plasmid-Carrying", 2, 2, 0.1258,
  0, "Plasmid-Carrying", 2, 3, 0.1788,
  0, "Plasmid-Carrying", 2, 4, 0.2178,
  0, "Plasmid-Carrying", 2, 5, 0.3678,
  0, "Plasmid-Carrying", 2, 6, 0.2208,
  0, "Plasmid-Carrying", 3, 1, 0.3528,
  0, "Plasmid-Carrying", 3, 2, 0.1358,
  0, "Plasmid-Carrying", 3, 3, 0.3578,
  0, "Plasmid-Carrying", 3, 4, 0.1828,
  0, "Plasmid-Carrying", 3, 5, 0.2538,
  0, "Plasmid-Carrying", 3, 6, 0.2068,

  1, "Plasmid-Free", 1, 1, 0.297,
  1, "Plasmid-Free", 1, 2, 0.175,
  1, "Plasmid-Free", 1, 3, 0.223,
  1, "Plasmid-Free", 1, 4, 0.124,
  1, "Plasmid-Free", 1, 5, 0.243,
  1, "Plasmid-Free", 1, 6, 0.304,
  1, "Plasmid-Free", 2, 1, 0.4,
  1, "Plasmid-Free", 2, 2, 0.187,
  1, "Plasmid-Free", 2, 3, 0.165,
  1, "Plasmid-Free", 2, 4, 0.226,
  1, "Plasmid-Free", 2, 5, 0.193,
  1, "Plasmid-Free", 2, 6, 0.438,
  1, "Plasmid-Free", 3, 1, 0.499,
  1, "Plasmid-Free", 3, 2, 0.287,
  1, "Plasmid-Free", 3, 3, 0.298,
  1, "Plasmid-Free", 3, 4, 0.352,
  1, "Plasmid-Free", 3, 5, 0.41,
  1, "Plasmid-Free", 3, 6, 0.456,
  1, "Plasmid-Carrying", 1, 1, 0.551,
  1, "Plasmid-Carrying", 1, 2, 0.113,
  1, "Plasmid-Carrying", 1, 3, 0.112,
  1, "Plasmid-Carrying", 1, 4, 0.235,
  1, "Plasmid-Carrying", 1, 5, 0.149,
  1, "Plasmid-Carrying", 1, 6, 0.358,
  1, "Plasmid-Carrying", 2, 1, 1.339,
  1, "Plasmid-Carrying", 2, 2, 0.781,
  1, "Plasmid-Carrying", 2, 3, 0.702,
  1, "Plasmid-Carrying", 2, 4, 0.764,
  1, "Plasmid-Carrying", 2, 5, 0.702,
  1, "Plasmid-Carrying", 2, 6, 0.727,
  1, "Plasmid-Carrying", 3, 1, 0.18,
  1, "Plasmid-Carrying", 3, 2, 0.173,
  1, "Plasmid-Carrying", 3, 3, 0.227,
  1, "Plasmid-Carrying", 3, 4, 0.272,
  1, "Plasmid-Carrying", 3, 5, 0.184,
  1, "Plasmid-Carrying", 3, 6, 0.153,

  2, "Plasmid-Free", 1, 1, 0.282,
  2, "Plasmid-Free", 1, 2, 0.389,
  2, "Plasmid-Free", 1, 3, 0.285,
  2, "Plasmid-Free", 1, 4, 0.441,
  2, "Plasmid-Free", 1, 5, 0.304,
  2, "Plasmid-Free", 1, 6, 0.444,
  2, "Plasmid-Free", 2, 1, 0.237,
  2, "Plasmid-Free", 2, 2, 0.344,
  2, "Plasmid-Free", 2, 3, 0.333,
  2, "Plasmid-Free", 2, 4, 0.243,
  2, "Plasmid-Free", 2, 5, 0.24,
  2, "Plasmid-Free", 2, 6, 0.445,
  2, "Plasmid-Free", 3, 1, 0.78,
  2, "Plasmid-Free", 3, 2, 0.845,
  2, "Plasmid-Free", 3, 3, 0.748,
  2, "Plasmid-Free", 3, 4, 0.946,
  2, "Plasmid-Free", 3, 5, 0.931,
  2, "Plasmid-Free", 3, 6, 0.904,
  2, "Plasmid-Carrying", 1, 1, 0.513,
  2, "Plasmid-Carrying", 1, 2, 0.563,
  2, "Plasmid-Carrying", 1, 3, 0.681,
  2, "Plasmid-Carrying", 1, 4, 0.431,
  2, "Plasmid-Carrying", 1, 5, 0.388,
  2, "Plasmid-Carrying", 1, 6, 0.256,
  2, "Plasmid-Carrying", 2, 1, 0.224,
  2, "Plasmid-Carrying", 2, 2, 0.376,
  2, "Plasmid-Carrying", 2, 3, 0.231,
  2, "Plasmid-Carrying", 2, 4, 0.297,
  2, "Plasmid-Carrying", 2, 5, 0.287,
  2, "Plasmid-Carrying", 2, 6, 0.352,
  2, "Plasmid-Carrying", 3, 1, 0.185,
  2, "Plasmid-Carrying", 3, 2, 0.168,
  2, "Plasmid-Carrying", 3, 3, 0.338,
  2, "Plasmid-Carrying", 3, 4, 0.273,
  2, "Plasmid-Carrying", 3, 5, 0.24,
  2, "Plasmid-Carrying", 3, 6, 0.294,

  3, "Plasmid-Free", 1, 1, 0.39,
  3, "Plasmid-Free", 1, 2, 0.274,
  3, "Plasmid-Free", 1, 3, 0.253,
  3, "Plasmid-Free", 1, 4, 0.334,
  3, "Plasmid-Free", 1, 5, 0.362,
  3, "Plasmid-Free", 1, 6, 0.272,
  3, "Plasmid-Free", 2, 1, 0.343,
  3, "Plasmid-Free", 2, 2, 0.176,
  3, "Plasmid-Free", 2, 3, 0.173,
  3, "Plasmid-Free", 2, 4, 0.128,
  3, "Plasmid-Free", 2, 5, 0.143,
  3, "Plasmid-Free", 2, 6, 0.262,
  3, "Plasmid-Free", 3, 1, 0.717,
  3, "Plasmid-Free", 3, 2, 0.558,
  3, "Plasmid-Free", 3, 3, 0.524,
  3, "Plasmid-Free", 3, 4, 0.6,
  3, "Plasmid-Free", 3, 5, 0.62,
  3, "Plasmid-Free", 3, 6, 0.688,
  3, "Plasmid-Carrying", 1, 1, 0.131,
  3, "Plasmid-Carrying", 1, 2, 0.254,
  3, "Plasmid-Carrying", 1, 3, 0.219,
  3, "Plasmid-Carrying", 1, 4, 0.077,
  3, "Plasmid-Carrying", 1, 5, 0.066,
  3, "Plasmid-Carrying", 1, 6, 0.159,
  3, "Plasmid-Carrying", 2, 1, 1.107,
  3, "Plasmid-Carrying", 2, 2, 0.951,
  3, "Plasmid-Carrying", 2, 3, 0.717,
  3, "Plasmid-Carrying", 2, 4, 0.558,
  3, "Plasmid-Carrying", 2, 5, 0.737,
  3, "Plasmid-Carrying", 2, 6, 0.906,
  3, "Plasmid-Carrying", 3, 1, 1.838,
  3, "Plasmid-Carrying", 3, 2, 1.376,
  3, "Plasmid-Carrying", 3, 3, 0.598,
  3, "Plasmid-Carrying", 3, 4, 0.19,
  3, "Plasmid-Carrying", 3, 5, 0.809,
  3, "Plasmid-Carrying", 3, 6, 1.261,

  4, "Plasmid-Free", 1, 1, 0.661,
  4, "Plasmid-Free", 1, 2, 0.856,
  4, "Plasmid-Free", 1, 3, 1.063,
  4, "Plasmid-Free", 1, 4, 0.903,
  4, "Plasmid-Free", 1, 5, 0.77,
  4, "Plasmid-Free", 1, 6, 1.394,
  4, "Plasmid-Free", 2, 1, 0.355,
  4, "Plasmid-Free", 2, 2, 0.282,
  4, "Plasmid-Free", 2, 3, 0.378,
  4, "Plasmid-Free", 2, 4, 0.488,
  4, "Plasmid-Free", 2, 5, 0.324,
  4, "Plasmid-Free", 2, 6, 0.445,
  4, "Plasmid-Free", 3, 1, 0.385,
  4, "Plasmid-Free", 3, 2, 0.382,
  4, "Plasmid-Free", 3, 3, 0.472,
  4, "Plasmid-Free", 3, 4, 0.344,
  4, "Plasmid-Free", 3, 5, 0.426,
  4, "Plasmid-Free", 3, 6, 0.829,
  4, "Plasmid-Carrying", 1, 1, 0.019,
  4, "Plasmid-Carrying", 1, 2, 0.026,
  4, "Plasmid-Carrying", 1, 3, 0.042,
  4, "Plasmid-Carrying", 1, 4, 0.043,
  4, "Plasmid-Carrying", 1, 5, 0.048,
  4, "Plasmid-Carrying", 1, 6, 0.026,
  4, "Plasmid-Carrying", 2, 1, 0.147,
  4, "Plasmid-Carrying", 2, 2, 0.155,
  4, "Plasmid-Carrying", 2, 3, 0.108,
  4, "Plasmid-Carrying", 2, 4, 0.156,
  4, "Plasmid-Carrying", 2, 5, 0.147,
  4, "Plasmid-Carrying", 2, 6, 0.123,
  4, "Plasmid-Carrying", 3, 2, 0.121,
  4, "Plasmid-Carrying", 3, 3, 0.075,
  4, "Plasmid-Carrying", 3, 4, 0.132,
  4, "Plasmid-Carrying", 3, 5, 0.164,
  4, "Plasmid-Carrying", 3, 6, 0.283,

  5, "Plasmid-Free", 1, 1, 1.025,
  5, "Plasmid-Free", 1, 2, 0.948,
  5, "Plasmid-Free", 1, 3, 0.867,
  5, "Plasmid-Free", 1, 4, 0.935,
  5, "Plasmid-Free", 1, 5, 0.705,
  5, "Plasmid-Free", 1, 6, 0.883,
  5, "Plasmid-Free", 2, 1, 0.647,
  5, "Plasmid-Free", 2, 2, 0.44,
  5, "Plasmid-Free", 2, 3, 0.438,
  5, "Plasmid-Free", 2, 4, 0.496,
  5, "Plasmid-Free", 2, 5, 0.439,
  5, "Plasmid-Free", 2, 6, 0.679,
  5, "Plasmid-Free", 3, 1, 0.683,
  5, "Plasmid-Free", 3, 2, 0.214,
  5, "Plasmid-Free", 3, 3, 0.539,
  5, "Plasmid-Free", 3, 4, 0.546,
  5, "Plasmid-Free", 3, 5, 0.544,
  5, "Plasmid-Free", 3, 6, 1.088,
  5, "Plasmid-Carrying", 1, 1, 0,
  5, "Plasmid-Carrying", 1, 2, 0.023,
  5, "Plasmid-Carrying", 1, 3, 0.073,
  5, "Plasmid-Carrying", 1, 4, 0.033,
  5, "Plasmid-Carrying", 1, 5, 0.048,
  5, "Plasmid-Carrying", 1, 6, 0.037,
  5, "Plasmid-Carrying", 2, 1, 0.356,
  5, "Plasmid-Carrying", 2, 2, 0.356,
  5, "Plasmid-Carrying", 2, 3, 0.474,
  5, "Plasmid-Carrying", 2, 4, 0.415,
  5, "Plasmid-Carrying", 2, 5, 0.456,
  5, "Plasmid-Carrying", 2, 6, 0.378,
  5, "Plasmid-Carrying", 3, 1, 0.189,
  5, "Plasmid-Carrying", 3, 2, 0.145,
  5, "Plasmid-Carrying", 3, 3, 0.153,
  5, "Plasmid-Carrying", 3, 4, 0.142,
  5, "Plasmid-Carrying", 3, 5, 0.132,
  5, "Plasmid-Carrying", 3, 6, 0.221
)

# Make factors
biofilm <- biofilm %>%
  mutate(
    Week = factor(Week, levels = 0:5),
    Population = factor(Population, levels = c("Plasmid-Free", "Plasmid-Carrying")),
    Biological_Replicate = factor(Biological_Replicate),
    Technical_Replicate = factor(Technical_Replicate)
  )

bio_means <- biofilm %>%
  group_by(Week, Population, Biological_Replicate) %>%
  summarise(
    mean_OD590 = mean(OD590, na.rm = TRUE),
    .groups = "drop"
  )

# Then summarize across biological replicates
summary_df <- bio_means %>%
  group_by(Week, Population) %>%
  summarise(
    mean_OD590 = mean(mean_OD590, na.rm = TRUE),
    sd_OD590   = sd(mean_OD590, na.rm = TRUE),
    n          = n(),
    se_OD590   = sd_OD590 / sqrt(n),
    .groups = "drop"
  )
# -----------------------------
#Main figure: raw data + bio replicate means + overall mean ± SE
# -----------------------------

p_main <- ggplot() +
  # raw technical replicates
  geom_jitter(
    data = biofilm,
    aes(x = Week, y = OD590, color = Population),
    width = 0.12, alpha = 0.18, size = 1.5
  ) +
  
  # biological replicate means (dashed lines)
  geom_line(
    data = bio_means,
    aes(x = Week, y = mean_OD590,
        group = interaction(Population, Biological_Replicate),
        color = Population),
    alpha = 0.3,
    linewidth = 0.8,
    linetype = "dashed"
  ) +
  
  geom_point(
    data = bio_means,
    aes(x = Week, y = mean_OD590, color = Population),
    alpha = 0.7,
    size = 2
  ) +
  
  # overall means (solid, bold)
  geom_line(
    data = summary_df,
    aes(x = Week, y = mean_OD590,
        color = Population,
        group = Population),
    linewidth = 1.6
  ) +
  
  geom_point(
    data = summary_df,
    aes(x = Week, y = mean_OD590, color = Population),
    size = 3
  ) +
  
  geom_errorbar(
    data = summary_df,
    aes(x = Week,
        ymin = mean_OD590 - se_OD590,
        ymax = mean_OD590 + se_OD590,
        color = Population),
    width = 0.15,
    linewidth = 0.8
  ) +
  
  # custom colors
  scale_color_manual(values = c(
    "Plasmid-Free" = "aquamarine4",
    "Plasmid-Carrying" = "violetred1"
  )) +
  
  labs(
    title = "Biofilm Biomass of Evolved Populations in Antibiotic-Free Conditions",
    subtitle = "Technical replicates shown as points; Biological replicates shown as dashed lines",
    x = "Week",
    y = "OD590"
  ) +
  theme_classic(base_size = 13) +
  theme(legend.position = "none")

p_main
p_reps <- ggplot(bio_means,
                 aes(x = Week, y = mean_OD590,
                     group = Biological_Replicate,
                     color = Population)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2.5) +
  facet_wrap(~Population) +
  labs(
    title = "Biological Replicate Means Across Time",
    x = "Week",
    y = "Mean OD590"
  ) +
  theme_classic(base_size = 13) +
   scale_color_manual(values = c(
    "Plasmid-Free" = "aquamarine4",
    "Plasmid-Carrying" = "violetred1"
  )) +
    theme(legend.position = "none")


p_reps
combined_plot <- p_main / p_reps +
  plot_layout(heights = c(2, 1))

combined_plot

library(lme4)
## Loading required package: Matrix
## 
## Attaching package: 'Matrix'
## The following objects are masked from 'package:tidyr':
## 
##     expand, pack, unpack
library(lmerTest)
## 
## Attaching package: 'lmerTest'
## The following object is masked from 'package:lme4':
## 
##     lmer
## The following object is masked from 'package:stats':
## 
##     step
model <- lmer(
  OD590 ~ Population * Week + (1 | Biological_Replicate),
  data = biofilm
)

summary(model)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: OD590 ~ Population * Week + (1 | Biological_Replicate)
##    Data: biofilm
## 
## REML criterion at convergence: 44.5
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.2558 -0.5521 -0.1283  0.4770  4.6233 
## 
## Random effects:
##  Groups               Name        Variance Std.Dev.
##  Biological_Replicate (Intercept) 0.00214  0.04626 
##  Residual                         0.06070  0.24637 
## Number of obs: 215, groups:  Biological_Replicate, 3
## 
## Fixed effects:
##                                    Estimate Std. Error         df t value
## (Intercept)                        0.374078   0.063916  30.710229   5.853
## PopulationPlasmid-Carrying        -0.171167   0.082122 200.998936  -2.084
## Week1                             -0.080911   0.082122 200.998936  -0.985
## Week2                              0.133756   0.082122 200.998936   1.629
## Week3                              0.004644   0.082122 200.998936   0.057
## Week4                              0.223533   0.082122 200.998936   2.722
## Week5                              0.299033   0.082122 200.998936   3.641
## PopulationPlasmid-Carrying:Week1   0.307000   0.116138 200.998936   2.643
## PopulationPlasmid-Carrying:Week2   0.002056   0.116138 200.998936   0.018
## PopulationPlasmid-Carrying:Week3   0.456556   0.116138 200.998936   3.931
## PopulationPlasmid-Carrying:Week4  -0.317629   0.116995 201.015305  -2.715
## PopulationPlasmid-Carrying:Week5  -0.300222   0.116138 200.998936  -2.585
##                                  Pr(>|t|)    
## (Intercept)                      1.93e-06 ***
## PopulationPlasmid-Carrying       0.038396 *  
## Week1                            0.325682    
## Week2                            0.104933    
## Week3                            0.954955    
## Week4                            0.007059 ** 
## Week5                            0.000345 ***
## PopulationPlasmid-Carrying:Week1 0.008855 ** 
## PopulationPlasmid-Carrying:Week2 0.985896    
## PopulationPlasmid-Carrying:Week3 0.000116 ***
## PopulationPlasmid-Carrying:Week4 0.007206 ** 
## PopulationPlasmid-Carrying:Week5 0.010444 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) PplP-C Week1  Week2  Week3  Week4  Week5  PP-C:W1 PP-C:W2
## PpltnPlsm-C -0.642                                                          
## Week1       -0.642  0.500                                                   
## Week2       -0.642  0.500  0.500                                            
## Week3       -0.642  0.500  0.500  0.500                                     
## Week4       -0.642  0.500  0.500  0.500  0.500                              
## Week5       -0.642  0.500  0.500  0.500  0.500  0.500                       
## PpltnP-C:W1  0.454 -0.707 -0.707 -0.354 -0.354 -0.354 -0.354                
## PpltnP-C:W2  0.454 -0.707 -0.354 -0.707 -0.354 -0.354 -0.354  0.500         
## PpltnP-C:W3  0.454 -0.707 -0.354 -0.354 -0.707 -0.354 -0.354  0.500   0.500 
## PpltnP-C:W4  0.451 -0.702 -0.351 -0.351 -0.351 -0.702 -0.351  0.496   0.496 
## PpltnP-C:W5  0.454 -0.707 -0.354 -0.354 -0.354 -0.354 -0.707  0.500   0.500 
##             PP-C:W3 PP-C:W4
## PpltnPlsm-C                
## Week1                      
## Week2                      
## Week3                      
## Week4                      
## Week5                      
## PpltnP-C:W1                
## PpltnP-C:W2                
## PpltnP-C:W3                
## PpltnP-C:W4  0.496         
## PpltnP-C:W5  0.500   0.496
anova(model)
week5 <- bio_means %>%
  filter(Week == "5")


wilcox.test(mean_OD590 ~ Population, data = week5)
## 
##  Wilcoxon rank sum exact test
## 
## data:  mean_OD590 by Population
## W = 9, p-value = 0.1
## alternative hypothesis: true location shift is not equal to 0
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.1     ✔ readr     2.2.0
## ✔ lubridate 1.9.5     ✔ stringr   1.6.0
## ✔ purrr     1.2.1     ✔ tibble    3.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ Matrix::expand() masks tidyr::expand()
## ✖ dplyr::filter()  masks stats::filter()
## ✖ dplyr::lag()     masks stats::lag()
## ✖ Matrix::pack()   masks tidyr::pack()
## ✖ Matrix::unpack() masks tidyr::unpack()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
diff_df <- tribble(
  ~Kanamycin, ~Week, ~MBIC,
  0,0,-0.2793333333,
  1,0,0.1675,
  2,0,0.3301666666,
  4,0,0.2676111112,
  8,0,0.0395,
  16,0,0.0837222222,
  32,0,0.04016666667,
  64,0,0.02927777778,
  128,0,0.03483333333,
  256,0,0.03527777777,

  0,1,0.0787777778,
  1,1,0.0323333333,
  2,1,0.0276666666,
  4,1,0.0067777778,
  8,1,0.0155555555,
  16,1,-0.1133333333,
  32,1,-0.0685555555,
  64,1,-0.03344444445,
  128,1,-0.02577777777,
  256,1,-0.018,

  0,2,0.1776666667,
  1,2,0.2084444445,
  2,2,0.2651111111,
  4,2,0.218,
  8,2,0.0973333333,
  16,2,0.1723333334,
  32,2,-0.0907777778,
  64,2,-0.00644444444,
  128,2,0.02044444445,
  256,2,0.03855555556,

  0,3,0.0641666667,
  1,3,-0.0809444445,
  2,3,0.0393888889,
  4,3,-0.2166111111,
  8,3,-0.2213888889,
  16,3,-0.3880555555,
  32,3,-0.7551666667,
  64,3,-0.0242777777,
  128,3,0.01038888889,
  256,3,-0.06983333333,

  0,4,-0.1016666666,
  1,4,-0.1762222222,
  2,4,-0.0924444444,
  4,4,-0.0251111111,
  8,4,0.0854444445,
  16,4,-0.0152222222,
  32,4,0.0376666667,
  64,4,0.086,
  128,4,0.1392222223,
  256,4,0.01188888889,

  0,5,0.0066888889,
  1,5,0.1715777778,
  2,5,0.1016888888,
  4,5,0.0485777778,
  8,5,0.0323555556,
  16,5,-0.2773111111,
  32,5,-0.1920888889,
  64,5,0.0291333333,
  128,5,0.0216888889,
  256,5,0.00913333334
)


diff_df <- diff_df %>%
  mutate(
    Week = factor(Week),
    Kanamycin = factor(Kanamycin)
  )

head(diff_df)
summary(diff_df)
##    Kanamycin  Week        MBIC           
##  0      : 6   0:10   Min.   :-0.7551667  
##  1      : 6   1:10   1st Qu.:-0.0422222  
##  2      : 6   2:10   Median : 0.0246778  
##  4      : 6   3:10   Mean   : 0.0001676  
##  8      : 6   4:10   3rd Qu.: 0.0800139  
##  16     : 6   5:10   Max.   : 0.3301667  
##  (Other):24
diff_df <- diff_df %>%
  mutate(
    Kanamycin_num = as.numeric(as.character(Kanamycin))
  )
p_heat <- ggplot(diff_df, aes(x = Week, y = Kanamycin, fill = MBIC)) +
  geom_tile(color = "white", linewidth = 0.6) +
  scale_fill_gradient2(
    low = "aquamarine4",
    mid = "white",
    high = "violetred1",
    midpoint = 0,
    name = "Δ Biomass (PC − PF)"
  ) +
  labs(
    title = "Context-Dependent Effect of Plasmid Carriage on Biofilm Tolerance",
    subtitle = "Pink favors Plasmid Carrying, Green favors Plasmid Free",
    x = "Week",
    y = "Kanamycin (µg/mL)"
  ) +
  theme_classic(base_size = 13) +
  theme(
  panel.grid.major = element_line(color = "gray90", linewidth = 0.3),
  panel.grid.minor = element_blank()
)

p_heat
library(tidyverse)

diff_summary <- diff_df %>%
  group_by(Week) %>%
  summarise(
    mean_diff = mean(MBIC, na.rm = TRUE),
    sd_diff   = sd(MBIC, na.rm = TRUE),
    n         = n(),
    se_diff   = sd_diff / sqrt(n),
    .groups = "drop"
  )

diff_summary <- diff_summary %>%
  mutate(
    Week_num = as.numeric(as.character(Week)),
    direction = case_when(
      mean_diff > 0 ~ "Plasmid Carrying Advantage",
      mean_diff < 0 ~ "Plasmid Free Advantage",
      TRUE ~ "Neutral"
    )
  )

diff_summary <- diff_summary %>%
  mutate(Week_num = as.numeric(as.character(Week)))

p_lollipop <- ggplot(diff_summary, aes(x = Week_num, y = mean_diff, color = direction)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray75", linewidth = 0.7) +
  geom_errorbar(aes(ymin = mean_diff - se_diff, ymax = mean_diff + se_diff),
                width = 0.12, linewidth = 1.1) +
  geom_point(size = 3.5) +
  scale_color_manual(values = c(
    "Plasmid Carrying Advantage" = "violetred1",
    "Plasmid Free Advantage" = "#3B7A57",
    "Neutral" = "gray30"
  )) +
  scale_x_continuous(breaks = 0:5) +
  labs(
    title = "Overall Effect of Plasmid Carriage on Biofilm Tolerance",
    subtitle = expression(Delta*"MBIC = Plasmid-Carrying - Plasmid-Free"),
    x = "Week",
    y = "Mean Difference in MBIC (PC - PF)"
  ) +
  theme_classic(base_size = 13) +
  theme(legend.position = "none")

p_lollipop
combined_plot <- p_lollipop / p_heat +
  plot_layout(height = c(1, 1))

combined_plot

diff_model <- lm(MBIC ~ factor(Week) * log2(Kanamycin_num + 1), data = diff_df)
anova(diff_model)
summary(diff_model)
## 
## Call:
## lm(formula = MBIC ~ factor(Week) * log2(Kanamycin_num + 1), data = diff_df)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.57255 -0.04043  0.00998  0.06801  0.24908 
## 
## Coefficients:
##                                        Estimate Std. Error t value Pr(>|t|)
## (Intercept)                            0.085486   0.084304   1.014    0.316
## factor(Week)1                         -0.046578   0.119224  -0.391    0.698
## factor(Week)2                          0.149838   0.119224   1.257    0.215
## factor(Week)3                         -0.192071   0.119224  -1.611    0.114
## factor(Week)4                         -0.197534   0.119224  -1.657    0.104
## factor(Week)5                         -0.032789   0.119224  -0.275    0.784
## log2(Kanamycin_num + 1)               -0.002775   0.018369  -0.151    0.881
## factor(Week)1:log2(Kanamycin_num + 1) -0.009960   0.025978  -0.383    0.703
## factor(Week)2:log2(Kanamycin_num + 1) -0.029974   0.025978  -1.154    0.254
## factor(Week)3:log2(Kanamycin_num + 1) -0.012297   0.025978  -0.473    0.638
## factor(Week)4:log2(Kanamycin_num + 1)  0.030751   0.025978   1.184    0.242
## factor(Week)5:log2(Kanamycin_num + 1) -0.012272   0.025978  -0.472    0.639
## 
## Residual standard error: 0.1473 on 48 degrees of freedom
## Multiple R-squared:  0.3684, Adjusted R-squared:  0.2237 
## F-statistic: 2.546 on 11 and 48 DF,  p-value: 0.01272