I\'m trying to calculate the doubling time of cells using a scatterplot. This is my dataframe
df = data.frame(\"x\" = 1:5, \"y\" = c(246, 667, 1715, 4867, 11694)
Plot log2(y)
vs. x
suppressing the Y axis so that we can build a nicer one. We also improved the Y axis label slightly. Then use axis
to build a pretty axis and calculate the doubling time. Note that the formula for doubling time in the question works if the rate constant is the slope of the log(y) ~ x regression line but if we use the regression log2(y) ~ x, i.e. log2 instead of log, then the correct formula is just 1/slope. We show both below.
plot(df$x, log2(df$y), xlab = "days", ylab = "cells/mL", yaxt = "n")
s <- 1:round(log2(max(df$y)))
axis(2, s, parse(text = sprintf("2^%d", s)))
fm <- lm(log2(y) ~ x, df)
abline(fm)
doubling.time <- 1/coef(fm)[[2]]
doubling.time
## [1] 0.7138163
log(2)/coef(lm(log(y) ~ x, df))[[2]] # same
## [1] 0.7138163
legend("topleft", paste("doubling time:", round(doubling.time, 3), "days"), bty = "n")
You can visualize the constant rate of change with ggplot2
by scaling the y-axis accordingly:
library(dplyr)
library(ggplot2)
library(broom)
library(scales)
df = data.frame("x" = 1:5, "y" = c(246, 667, 1715, 4867, 11694))
fit <- lm(data = df, log2(y) ~ x)
tidy_fit <- tidy(fit) %>%
mutate(x = 3, y = 2048)
ggplot(df, aes(x = x, y = y)) +
geom_point() +
scale_y_continuous(name = "log2(y)",
trans = 'log2',
breaks = trans_breaks("log2", function(x) 2^x),
labels = trans_format("log2", math_format(2^.x))) +
geom_smooth(method = "lm", se = FALSE) +
geom_text(tidy_fit,
mapping = aes(
x = x,
y = y,
label = paste0("log2(y) = ", round(estimate[1], 2), " + ", round(estimate[2], 2), "x",
"\n", "Doubling Time: ", round(1 / tidy_fit$estimate[2], 2), " Days")
),
nudge_x = -1,
nudge_y = 0.5,
hjust = 0)
Created on 2020-02-03 by the reprex package (v0.3.0)
You can plot the points to show the exponential rise and then linearize the function by applying log2 to the y values. With that you can plot and do a linear fit:
df = data.frame("x" = 1:5, "y" = c(246, 667, 1715, 4867, 11694))
plot(df) # plot not displayed
plot(df$x, log2(df$y))
abline(lm(log2(y)~x,df))
lm(log2(y)~x,df)
#-------------------
Call:
lm(formula = log2(y) ~ x, data = df)
Coefficients:
(Intercept) x
6.563 1.401 #the x-coefficient is the slope of the line
#---------------------
log(2)/1.4
#[1] 0.4951051
Checking with the original (not-displayed plot that does look like a sensible estimate of doubling time. Be sure to cite this posting if this happens to be a homework problem.
If I were tasked with using the original graph, first draw an exponential curve by hand. I would then draw two horizontal lines at y= 2000 and y=4000 and then drop perpendicular lines from their intersections with the curve and read off the difference in x values on the horizontal axis.That is what I meant by my comment above that I "checked" the log2/x-coef value for sensibility.