1
votes

I've got some data that looks like a logistic growth curve. I can put a loess curve on it with geom_smooth, but I'd like to fit a proper logistic curve

data <- data.frame(conc = c(10, 1, 0.1, 0.01, 0.001, 1e-04, 1e-05, 1e-06, 1e-07, 1e-08, 
                            1e-09, 10, 1, 0.1, 0.01, 0.001, 1e-04, 1e-05, 1e-06, 1e-07, 1e-08, 
                            1e-09, 10, 1, 0.1, 0.01, 0.001, 1e-04, 1e-05, 1e-06, 1e-08, 1e-09, 
                            10, 1, 0.1, 0.01, 0.001, 1e-04, 1e-05, 1e-06, 1e-08, 1e-09, 1e-10),
                   value = c(22832, 26910, 9303, 4128, 521, 44, 64, 31, 50, 39, 284, 19993, 
                             24205, 9230, 4030, 447, 42, 51, 175, 38, 35, 161, 23072, 27382, 
                             7036, 2416, 320, 58, 30, 37, 40, 110, 26630, 28568, 6262, 2854, 
                             314, 102, 50, 39, 34, 77, 30))
ggplot(data, aes(x=conc, y=value)) +
  geom_point() +
  geom_smooth() +
  scale_x_continuous(trans = 'log10')

I've read around and tried with this:

stat_smooth(method="glm", method.args=list(family="binomial"), se=FALSE)```

But I keep getting this error:

geom_smooth()` using formula 'y ~ x'
Warning message:
Computation failed in `stat_smooth()`:
y values must be 0 <= y <= 1

I'm aiming for something like this:

enter image description here

2

2 Answers

2
votes

Something like this???

ggplot(data, aes(x=conc, y=value/max(value))) +
  geom_point() +
  # geom_smooth() +
  # scale_x_continuous(trans = 'log10')
  stat_smooth(formula = "y ~ x", method = "glm", 
              method.args = list(family="quasibinomial"), se = T) +
  scale_y_continuous(labels = function(x) x * max(data$value))

enter image description here

2
votes

To fit a four-parameters logistic curve, you can do:

library(ggplot2)
library(nlme)

ggplot(data, aes(x=conc, y=value)) +
  geom_point() +
  geom_smooth(
    method = "nls", formula = y ~ SSfpl(log(x), A, B, xmid, scal),
    se = FALSE
  ) 

But there's a singular gradient with your data, hence an error is generated. This works if one fits the logarithm of value:

ggplot(data, aes(x=conc, y=log(value))) +
  geom_point() +
  geom_smooth(
    method = "nls", formula = y ~ SSfpl(log(x), A, B, xmid, scal),
    se = FALSE
  )