Read in Data

For publication in MicroBiology Open, or backup (Yeast, FEMS Yeast Reserach, Journal of Basic Microbiology)

data=read.csv("CombinedData.csv")

Chat GPT Input: I need to go from wide to long format in R. Columns are samples (A, B,C) and dose (0,5,10,25). It appended a number for replications (A.10.1, A.10.2) So this would be Sample A, dose of 10, replicates 1 and 2. Please provide code to go to long format. Include a screenshot of the data.

Change Data to Long Format

We converted the dataset from a wide format to a long format to make it easier to analyze and visualize in R using tidyverse tools. Originally, each column represented a unique experimental condition, where the column names encoded the sample identity (e.g., A or B), dosage level (0, 5, 10, or 25), and replicate number (e.g., .1 or .2). Using pivot_longer(), we combined all measurement columns into a single response column (OD) while preserving the time variable. We then used separate() to split the original column names into three new variables: Sample, Dose, and Replicate. Missing replicate identifiers were assigned a value of 0, allowing columns such as A.10, A.10.1, and A.10.2 to be interpreted consistently as replicate 0, 1, and 2 of Sample A at dose 10. This restructuring produces a tidy dataset in which each row represents a single observation at one time point, making downstream statistical analysis and ggplot visualization much more straightforward.

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.0     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.2     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidyverse)  # Loads the tidyverse collection of data wrangling packages

dat_long <- data %>%
  tidyr::pivot_longer(
    cols = -Time,
    names_to = "well_name",
    values_to = "OD"
  ) %>%
  dplyr::mutate(
    is_blank = stringr::str_detect(well_name, "^Blank"),
    Sample = dplyr::if_else(
      is_blank,
      "Blank",
      stringr::str_extract(well_name, "^[A-H]")
    ),
    Glucose = dplyr::if_else(
      is_blank,
      "4YPD",
      stringr::str_extract(well_name, "(?<=_)[0-9.]+(?=_)")
    ),
    Replicate = dplyr::if_else(
      is_blank,
      stringr::str_extract(well_name, "[A-H][0-9]+$"),
      stringr::str_extract(well_name, "(?<=_[0-9.]_)[0-9]+|(?<=_[0-9][.]?[0-9]?_)[0-9]+")
    ),
    Treatment = dplyr::case_when(
      stringr::str_detect(well_name, "_Met") ~ "Met",
      stringr::str_detect(well_name, "_Control") ~ "Control",
      stringr::str_detect(well_name, "_NoMet") ~ "Control",
      TRUE ~ "Control"
    ),
    BioRep = paste(Sample, Replicate, sep = "_")
  ) %>%
  dplyr::filter(Sample != "Blank") %>%
  dplyr::filter(Glucose != "4")

#Statistical Comparison

growth_dat <- dat_long %>%
  dplyr::group_by(Time, Glucose, BioRep, Treatment) %>%
  dplyr::summarize(
    OD = mean(OD, na.rm = TRUE),
    .groups = "drop"
  )

growth_summary <- growth_dat %>%
  dplyr::group_by(Time, Glucose, Treatment) %>%
  dplyr::summarize(
    Mean_OD = mean(OD, na.rm = TRUE),
    SE = sd(OD, na.rm = TRUE) / sqrt(dplyr::n()),
    .groups = "drop"
  )

head(growth_dat)
## # A tibble: 6 × 5
##   Time    Glucose BioRep Treatment    OD
##   <chr>   <chr>   <chr>  <chr>     <dbl>
## 1 0:00:00 0.5     A_1    Control   0.216
## 2 0:00:00 0.5     A_1    Met       0.202
## 3 0:00:00 0.5     A_2    Control   0.225
## 4 0:00:00 0.5     A_2    Met       0.203
## 5 0:00:00 0.5     A_3    Control   0.250
## 6 0:00:00 0.5     A_3    Met       0.218
nrow(growth_dat)
## [1] 9024
library(lubridate)

library(tidyverse)

growth_summary <- growth_summary %>%
  mutate(
    Time_chr = as.character(Time),

    # Split off day if SoftMax uses format like 1.00:30:00
    Day = ifelse(str_detect(Time_chr, "\\."),
                 as.numeric(str_extract(Time_chr, "^[0-9]+")),
                 0),

    Time_no_day = ifelse(str_detect(Time_chr, "\\."),
                         str_replace(Time_chr, "^[0-9]+\\.", ""),
                         Time_chr),

    Hours = as.numeric(str_extract(Time_no_day, "^[0-9]+")),
    Minutes = as.numeric(str_extract(Time_no_day, "(?<=:)[0-9]+")),
    
    Time_hr = Day * 24 + Hours + Minutes / 60
  )

growth_summary %>%
  select(Time, Time_hr) %>%
  distinct() %>%
  tail(20)
## # A tibble: 20 × 2
##    Time     Time_hr
##    <chr>      <dbl>
##  1 22:00:00    22  
##  2 22:30:00    22.5
##  3 23:00:00    23  
##  4 23:30:00    23.5
##  5 2:00:00      2  
##  6 2:30:00      2.5
##  7 3:00:00      3  
##  8 3:30:00      3.5
##  9 4:00:00      4  
## 10 4:30:00      4.5
## 11 5:00:00      5  
## 12 5:30:00      5.5
## 13 6:00:00      6  
## 14 6:30:00      6.5
## 15 7:00:00      7  
## 16 7:30:00      7.5
## 17 8:00:00      8  
## 18 8:30:00      8.5
## 19 9:00:00      9  
## 20 9:30:00      9.5
#install.packages("colorspace")   # if needed
library(colorspace)

ggplot(
  growth_summary,
  aes(
    x = Time_hr,
    y = Mean_OD,
    color = Treatment,
    fill = Treatment
  )
) +
  geom_ribbon(
    aes(
      ymin = Mean_OD - SE,
      ymax = Mean_OD + SE
    ),
    alpha = 0.2,
    color = NA
  ) +
  geom_line(linewidth = 1.2) +
scale_color_discrete_sequential(palette = "DarkMint") +
scale_fill_discrete_sequential(palette = "DarkMint") +
  facet_wrap(~ Glucose, nrow = 1) +
  labs(
    x = "Time (hours)",
    y = "Mean OD600 ± SE",
    color = "Treatment",
    fill = "Treatment"
  ) +
  theme_classic(base_size = 14)

ggplot(
  growth_summary,
  aes(
    x = Time_hr,
    y = Mean_OD,
    color = Treatment,
    fill = Treatment
  )
) +
  geom_ribbon(
    aes(
      ymin = Mean_OD - SE,
      ymax = Mean_OD + SE
    ),
    alpha = 0.2,
    color = NA
  ) +
  geom_line(linewidth = 1.2) +
  facet_wrap(~ Glucose, nrow = 1) +
  labs(
    x = "Time (hours)",
    y = "Mean OD600 ± SE",
    color = "Treatment",
    fill = "Treatment"
  ) +
  scale_color_discrete_sequential(palette = "DarkMint") +
scale_fill_discrete_sequential(palette = "DarkMint") +
  theme_classic(base_size = 14) +
coord_cartesian(
  ylim = c(0.9, 1.5)
)

Growth curves were generated to examine the effects of prior glucose history and metformin treatment on yeast proliferation during 48 hours of refeeding. Cultures conditioned in either 0.5% or 2% glucose exhibited similar growth dynamics, with all groups rapidly entering exponential growth and reaching comparable stationary-phase optical densities. Metformin treatment (10 mM) produced only subtle differences in growth, including a slightly shorter lag phase and marginally higher final optical density, but no large inhibitory or stimulatory effects were observed. Overall, these data suggest that metformin at the selected concentration has minimal influence on overall cell proliferation during refeeding.

AUC

library(MESS)

growth_dat <- growth_dat %>%
  mutate(Time = as.character(Time))

# Check if days are present
growth_dat %>%
  filter(grepl("\\.", Time)) %>%
  select(Time) %>%
  distinct()
## # A tibble: 46 × 1
##    Time      
##    <chr>     
##  1 1.00:00:00
##  2 1.00:30:00
##  3 1.01:00:00
##  4 1.01:30:00
##  5 1.02:00:00
##  6 1.02:30:00
##  7 1.03:00:00
##  8 1.03:30:00
##  9 1.04:00:00
## 10 1.04:30:00
## # ℹ 36 more rows
growth_dat <- growth_dat %>%
  mutate(
    Day = ifelse(
      grepl("\\.", Time),
      as.numeric(sub("\\..*", "", Time)),
      0
    ),

    Time_no_day = ifelse(
      grepl("\\.", Time),
      sub("^[0-9]+\\.", "", Time),
      Time
    )
  ) %>%
  separate(
    Time_no_day,
    into = c("Hour","Minute","Second"),
    sep = ":",
    convert = TRUE
  ) %>%
  mutate(
    Time_hr = Day*24 + Hour + Minute/60
  )
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `Day = ifelse(...)`.
## Caused by warning in `ifelse()`:
## ! NAs introduced by coercion
auc_dat <- growth_dat %>%
  ungroup() %>%
  group_by(
    .data$Glucose,
    .data$BioRep,
    .data$Treatment,
    .data$Time_hr
  ) %>%
  dplyr::summarize(
    OD_mean = mean(.data$OD, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  dplyr::arrange(
    .data$Glucose,
    .data$BioRep,
    .data$Treatment,
    .data$Time_hr
  ) %>%
  group_by(
    .data$Glucose,
    .data$BioRep,
    .data$Treatment
  ) %>%
  dplyr::summarize(
    AUC = MESS::auc(.data$Time_hr, .data$OD_mean),
    .groups = "drop"
  )

ggplot(
  auc_dat,
  aes(x = Treatment, y = AUC, fill = Treatment)
) +
  geom_boxplot(alpha = 0.7, outlier.shape = NA) +
  geom_jitter(width = 0.1, size = 3) +
  facet_wrap(~ Glucose) +
  theme_classic(base_size = 14) +
  scale_color_discrete_sequential(palette = "DarkMint") +
scale_fill_discrete_sequential(palette = "DarkMint") +
  labs(
    x = "Treatment",
    y = "Area under the growth curve",
    fill = "Treatment"
  )
## Warning: Removed 60 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Warning: Removed 60 rows containing missing values or values outside the scale range
## (`geom_point()`).

model_auc <- lm(AUC ~ Glucose * Treatment, data = auc_dat)

anova(model_auc)
## Analysis of Variance Table
## 
## Response: AUC
##                   Df  Sum Sq Mean Sq F value Pr(>F)
## Glucose            1   4.348  4.3479  0.4412 0.5113
## Treatment          1  20.263 20.2628  2.0562 0.1613
## Glucose:Treatment  1   5.291  5.2912  0.5369 0.4690
## Residuals         32 315.337  9.8543
summary(model_auc)
## 
## Call:
## lm(formula = AUC ~ Glucose * Treatment, data = auc_dat)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -5.9895 -1.7937  0.1551  2.4835  4.3374 
## 
## Coefficients:
##                       Estimate Std. Error t value Pr(>|t|)    
## (Intercept)           60.80081    1.04638  58.106   <2e-16 ***
## Glucose2              -0.07169    1.47981  -0.048    0.962    
## TreatmentMet           0.73372    1.47981   0.496    0.623    
## Glucose2:TreatmentMet  1.53350    2.09277   0.733    0.469    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.139 on 32 degrees of freedom
##   (60 observations deleted due to missingness)
## Multiple R-squared:  0.08661,    Adjusted R-squared:  0.0009822 
## F-statistic: 1.011 on 3 and 32 DF,  p-value: 0.4004
aucdat2=subset(auc_dat, Glucose != 4)
model_auc2 <- lm(AUC ~ Glucose * Treatment, data = aucdat2)
anova(model_auc2)
## Analysis of Variance Table
## 
## Response: AUC
##                   Df  Sum Sq Mean Sq F value Pr(>F)
## Glucose            1   4.348  4.3479  0.4412 0.5113
## Treatment          1  20.263 20.2628  2.0562 0.1613
## Glucose:Treatment  1   5.291  5.2912  0.5369 0.4690
## Residuals         32 315.337  9.8543
library(emmeans)
## Welcome to emmeans.
## Caution: You lose important information if you filter this package's results.
## See '? untidy'
emm_auc <- emmeans(
  model_auc2,
  ~ Treatment | Glucose
)

pairs(emm_auc)
## Glucose = 0.5:
##  contrast      estimate   SE df t.ratio p.value
##  Control - Met   -0.734 1.48 32  -0.496  0.6234
## 
## Glucose = 2:
##  contrast      estimate   SE df t.ratio p.value
##  Control - Met   -2.267 1.48 32  -1.532  0.1353
summary(emm_auc)
## Glucose = 0.5:
##  Treatment emmean   SE df lower.CL upper.CL
##  Control     60.8 1.05 32     58.7     62.9
##  Met         61.5 1.05 32     59.4     63.7
## 
## Glucose = 2:
##  Treatment emmean   SE df lower.CL upper.CL
##  Control     60.7 1.05 32     58.6     62.9
##  Met         63.0 1.05 32     60.9     65.1
## 
## Confidence level used: 0.95

To quantify cumulative growth over the 48-hour experiment, the area under each growth curve (AUC) was calculated for each biological replicate. Although metformin-treated cultures exhibited slightly higher AUC values than untreated controls in both glucose histories, linear modeling detected no significant effects of glucose history, metformin treatment, or their interaction (all P > 0.30). These findings indicate that neither prior nutritional history nor metformin substantially altered total biomass accumulation over the duration of the experiment, supporting the conclusion that 10 mM metformin has relatively modest effects on overall growth.

Maximum Growth Rate

growth_rate_dat <- growth_dat %>%
  dplyr::group_by(Glucose, BioRep, Treatment) %>%
  dplyr::arrange(Time_hr, .by_group = TRUE) %>%
  dplyr::mutate(
    growth_rate = (OD - dplyr::lag(OD)) /
      (Time_hr - dplyr::lag(Time_hr))
  ) %>%
  dplyr::summarize(
    max_growth_rate = max(growth_rate, na.rm = TRUE),
    .groups = "drop"
  )

model_rate <- lm(
  max_growth_rate ~ Glucose * Treatment,
  data = growth_rate_dat
)

anova(model_rate)
## Analysis of Variance Table
## 
## Response: max_growth_rate
##                   Df  Sum Sq  Mean Sq F value Pr(>F)
## Glucose            1 0.00402 0.004021  0.2168 0.6426
## Treatment          1 0.01479 0.014793  0.7976 0.3741
## Glucose:Treatment  1 0.03293 0.032934  1.7757 0.1860
## Residuals         92 1.70632 0.018547
library(emmeans)

emmeans(model_rate, ~ Treatment | Glucose) %>%
  pairs()
## Glucose = 0.5:
##  contrast      estimate     SE df t.ratio p.value
##  Control - Met  -0.0122 0.0393 92  -0.311  0.7567
## 
## Glucose = 2:
##  contrast      estimate     SE df t.ratio p.value
##  Control - Met   0.0619 0.0393 92   1.574  0.1190
ggplot(
  growth_rate_dat,
  aes(
    x = Treatment,
    y = max_growth_rate,
    fill = Treatment
  )
) +
  geom_boxplot(
    width = 0.6,
    alpha = 0.85,
    outlier.shape = NA
  ) +
  geom_jitter(
    width = 0.12,
    size = 2.5,
    alpha = 0.9
  ) +
  facet_wrap(~Glucose) +
  scale_color_discrete_sequential(palette = "DarkMint") +
scale_fill_discrete_sequential(palette = "DarkMint") +  
  labs(
    x = "Treatment",
    y = "Maximum Growth Rate"
  ) +
  theme_classic(base_size = 14) +
  theme(
    legend.position = "right",
    strip.background = element_blank(),
    strip.text = element_text(face = "bold"),
    axis.title = element_text(face = "bold")
  )

Lag Time

lag_dat <- growth_dat %>%
  dplyr::group_by(Glucose, BioRep, Treatment) %>%
  dplyr::filter(OD >= 0.5) %>%
  dplyr::slice_min(Time_hr, n = 1) %>%
  dplyr::ungroup() %>%
  dplyr::select(
    Glucose,
    BioRep,
    Treatment,
    lag_time_05 = Time_hr
  )

model_lag <- lm(
  lag_time_05 ~ Glucose * Treatment,
  data = lag_dat
)

anova(model_lag)
## Analysis of Variance Table
## 
## Response: lag_time_05
##                   Df  Sum Sq Mean Sq F value Pr(>F)
## Glucose            1   0.375 0.37500  0.1333 0.7159
## Treatment          1   2.667 2.66667  0.9478 0.3328
## Glucose:Treatment  1   0.094 0.09375  0.0333 0.8556
## Residuals         92 258.854 2.81363
emmeans(model_lag, ~ Treatment | Glucose) %>%
  pairs()
## Glucose = 0.5:
##  contrast      estimate    SE df t.ratio p.value
##  Control - Met    0.271 0.484 92   0.559  0.5773
## 
## Glucose = 2:
##  contrast      estimate    SE df t.ratio p.value
##  Control - Met    0.396 0.484 92   0.817  0.4158
ggplot(
  lag_dat,
  aes(
    x = Treatment,
    y = lag_time_05,
    fill = Treatment
  )
) +
  geom_boxplot(
    width = 0.6,
    alpha = 0.85,
    outlier.shape = NA
  ) +
  geom_jitter(
    width = 0.12,
    size = 2.5,
    alpha = 0.9
  ) +
  facet_wrap(~Glucose) +
  scale_color_discrete_sequential(palette = "DarkMint") +
scale_fill_discrete_sequential(palette = "DarkMint") +    labs(
    x = "Treatment",
    y = "Time to OD600 = 0.5 (hours)"
  ) +
  theme_classic(base_size = 14) +
  
  theme(
    legend.position = "right",
    strip.background = element_blank(),
    strip.text = element_text(face = "bold"),
    axis.title = element_text(face = "bold")
  )

Maximum OD

max_od_dat <- growth_dat %>%
  dplyr::group_by(Glucose, BioRep, Treatment) %>%
  dplyr::summarize(
    max_OD = max(OD, na.rm = TRUE),
    .groups = "drop"
  )

model_maxOD <- lm(
  max_OD ~ Glucose * Treatment,
  data = max_od_dat
)

anova(model_maxOD)
## Analysis of Variance Table
## 
## Response: max_OD
##                   Df  Sum Sq   Mean Sq F value Pr(>F)
## Glucose            1 0.00084 0.0008366  0.2189 0.6410
## Treatment          1 0.00527 0.0052718  1.3791 0.2433
## Glucose:Treatment  1 0.00181 0.0018053  0.4723 0.4937
## Residuals         92 0.35168 0.0038226
emmeans(model_maxOD, ~ Treatment | Glucose) %>%
  pairs()
## Glucose = 0.5:
##  contrast      estimate     SE df t.ratio p.value
##  Control - Met -0.02349 0.0178 92  -1.316  0.1913
## 
## Glucose = 2:
##  contrast      estimate     SE df t.ratio p.value
##  Control - Met -0.00615 0.0178 92  -0.344  0.7313
ggplot(
  max_od_dat,
  aes(
    x = Treatment,
    y = max_OD,
    fill = Treatment
  )
) +
  geom_boxplot(
    width = 0.6,
    alpha = 0.85,
    outlier.shape = NA
  ) +
  geom_jitter(
    width = 0.12,
    size = 2.5,
    alpha = 0.9
  ) +
  facet_wrap(~Glucose) +
  scale_color_discrete_sequential(palette = "DarkMint") +
scale_fill_discrete_sequential(palette = "DarkMint") +   labs(
    x = "Treatment",
    y = "Maximum OD600"
  ) +
  theme_classic(base_size = 14) +
  theme(
    legend.position = "right",
    strip.background = element_blank(),
    strip.text = element_text(face = "bold"),
    axis.title = element_text(face = "bold")
  )

Nile Red

nile_raw=read.csv("Sonja_NR_complete.csv")

library(tidyverse)

nile_summary <- nile_raw %>%
  dplyr::group_by(History, Replicate, Treatment) %>%
  dplyr::summarize(
    Mean_Fluorescence = mean(Reading, na.rm = TRUE),
    .groups = "drop"
  )

nile_summary
## # A tibble: 36 × 4
##    History Replicate Treatment Mean_Fluorescence
##      <dbl> <chr>     <chr>                 <dbl>
##  1     0.5 A         Control                285.
##  2     0.5 A         Metformin              466.
##  3     0.5 B         Control                348.
##  4     0.5 B         Metformin              468.
##  5     0.5 C         Control                223.
##  6     0.5 C         Metformin              541.
##  7     0.5 D         Control                161.
##  8     0.5 D         Metformin              275.
##  9     0.5 E         Control                290.
## 10     0.5 E         Metformin              131.
## # ℹ 26 more rows
ggplot(
  nile_summary,
  aes(x = Treatment, y = Mean_Fluorescence, fill = Treatment)
) +
  geom_boxplot(alpha = 0.7, outlier.shape = NA) +
  geom_jitter(width = 0.1, size = 3) +
  facet_wrap(~ History) +
  theme_classic(base_size = 14) +
    scale_color_discrete_sequential(palette = "DarkMint") +
scale_fill_discrete_sequential(palette = "DarkMint") +
  labs(
    x = "Treatment",
    y = "Nile Red fluorescence",
    fill = "Treatment"
  )

model_nile <- lm(
  Mean_Fluorescence ~ as.factor(History) * Treatment,
  data = nile_summary
)

anova(model_nile)
## Analysis of Variance Table
## 
## Response: Mean_Fluorescence
##                              Df Sum Sq Mean Sq F value  Pr(>F)  
## as.factor(History)            1  52331   52331  6.8609 0.01336 *
## Treatment                     1  20778   20778  2.7240 0.10863  
## as.factor(History):Treatment  1  11691   11691  1.5328 0.22471  
## Residuals                    32 244080    7628                  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(model_nile)
## 
## Call:
## lm(formula = Mean_Fluorescence ~ as.factor(History) * Treatment, 
##     data = nile_summary)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -192.051  -51.621    2.779   52.067  218.444 
## 
## Coefficients:
##                                        Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                              238.94      29.11   8.208 2.24e-09 ***
## as.factor(History)2                      -40.21      41.17  -0.977   0.3360    
## TreatmentMetformin                        84.09      41.17   2.042   0.0494 *  
## as.factor(History)2:TreatmentMetformin   -72.08      58.22  -1.238   0.2247    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 87.34 on 32 degrees of freedom
## Multiple R-squared:  0.2578, Adjusted R-squared:  0.1883 
## F-statistic: 3.706 on 3 and 32 DF,  p-value: 0.02143
library(emmeans)

emm_nile <- emmeans(
  model_nile,
  ~ Treatment | History
)

pairs(emm_nile)
## History = 0.5:
##  contrast            estimate   SE df t.ratio p.value
##  Control - Metformin    -84.1 41.2 32  -2.042  0.0494
## 
## History = 2.0:
##  contrast            estimate   SE df t.ratio p.value
##  Control - Metformin    -12.0 41.2 32  -0.292  0.7725

Neutral lipid accumulation was assessed using Nile Red fluorescence following 48 hours of refeeding. In contrast to the growth analyses, glucose history significantly influenced lipid accumulation (P = 0.013), whereas the overall effect of metformin was not significant (P = 0.109). However, post hoc comparisons revealed that metformin significantly increased Nile Red fluorescence in cells previously conditioned under nutrient restriction (0.5% glucose; P = 0.049), while no significant effect of metformin was observed in cells conditioned in 2% glucose. These findings suggest that prior nutritional history alters the metabolic response to metformin despite having relatively little effect on overall cell growth, supporting the hypothesis that nutrient restriction induces persistent metabolic changes that influence subsequent responses during refeeding.

What this might mean:

The common teaching is that metformin “reduces lipid accumulation.” That’s an oversimplification. Metformin’s primary action is not to directly inhibit lipid synthesis. Instead, it alters cellular energy sensing by inhibiting mitochondrial respiration (Complex I in mammalian cells) and activating energy-stress pathways such as AMPK (or the analogous SNF1 pathway in yeast). The downstream effects depend heavily on the cell’s metabolic state.

In mammalian cells, metformin generally:

  • decreases ATP production,
  • activates AMPK,
  • suppresses mTOR signaling,
  • decreases de novo lipogenesis,
  • increases fatty acid oxidation,
  • reduces hepatic glucose production.

Because of these downstream effects, metformin often reduces lipid accumulation in obesity and type II diabetes.

However, those studies are almost always performed in metabolically unhealthy or nutrient-replete systems. Your experiment is asking a different question:What happens when the cell first experiences nutrient deprivation and is then refed? We know much less about this.

So, why might restricted cells accumulate more lipid: 1. Metabolic memory. After prolonged restriction, cells become metabolically programmed to conserve resources. So rather than investing carbon into new biomass, it diverts carbon into neutral lipid storage. 2. Growth and storage become uncoupled. Growth hardly changed.Nile Red changed substantially. That means metformin probably isn’t changing how much glucose the cells take up (which would lead to growth).Instead, it is changing where that carbon goes. 3. Nutrient signaling is different. Cells previously grown in 0.5% have higher SNF1, altered TOR, or different carbon reserve metabolism.

Considerations for moving forward:

  1. My recommendation, focus on the “how” part:
  • In previously restricted cells, does metformin increase lipid accumulation by increasing lipid synthesis/storage, decreasing lipid breakdown, or shifting carbon away from growth and into storage?
  • This would be done by running qPCR on storage/metabolism genes
  • Start by looking into these:
Category Genes
TAG/lipid storage DGA1, LRO1
Fatty acid synthesis ACC1
Lipid breakdown TGL3, TGL4
Energy sensing SNF1
Growth/nutrient signaling TOR1, SCH9
Carbohydrate storage GSY1/GSY2, TPS1/TPS2
  • Is the extra Nile Red signal due to increased lipid synthesis or decreased lipid utilization?
  • That determines the molecular direction.
  • If it’s increased synthesis, I’d examine genes like ACC1, DGA1, and LRO1.
  • If it’s decreased utilization, I’d focus on TGL3, TGL4, and β-oxidation pathways.
  1. Other options:
  • Do a time series of Nile Red (Measure the accumulation at 6h, 12h, 24h)
  • Recovery experiment: After 48h of refeeding, remove metforming and grow cells again at normal media. (Is the effect reversible)
  • Storage tradeoff experiment: Measure glycogen or trehalose. Are restricted cells storing carbon specifically as lipids, or generally as storage molecules.
  • Stress tolerance assay. After restriction/refeeding, expose cells to mild stress (peroxide, heat shock, salt) and see if metabolic history changes later stress resistance.