Daniel Valencia C.
Daniel Valencia C.

Reputation: 2279

How to assign different initial values inside geom_smooth() (from the ggplot2 package) for multiple nonlinear regressions?

I have 2 datasets, one for group A and one for group B. I want to visually fit the data into the y=1-exp(-kx) model. For this I'm using the ggplot2 package and the geom_smooth() function. Within the arguments of the geom_smooth() function it is necessary to indicate initial values for non-linear fits. As I have 2 sets of data, I would like to assign different initial values to each set. In this case, for group A the initial value of k would be 0.45 and for group B it would be 0.015. However, I don't know how to do this. Can anybody help me?

library(ggplot2)


Group <- c("A", "B")
x <- 0:10
y <- c(0, 0.4, 0.6, 0.8, 0.9, 0.9, 0.95, 0.97, 0.98, 0.99, 1,
       0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1)
start_values <- c(0.45, 0.015)

df <- expand.grid(x = x,
                  Group = Group)

df$y <- y

ggplot(data = df,
       aes(x = x,
           y = y)) +
  geom_point(aes(shape = Group,
                 color = Group)) +
  geom_smooth(aes(color = Group),
              formula = y ~ 1-exp(-k*x),
              method = "nls",
              method.args = list(k = start_values),
              se = FALSE)

enter image description here

Upvotes: 2

Views: 659

Answers (1)

MrFlick
MrFlick

Reputation: 206536

As far as I can tell, you cannot easily pass different parameters for each group using geom_smooth. One option would be to add separate layers for each of the groups

ggplot(data = df,
       aes(x = x,
           y = y)) +
  geom_point(aes(shape = Group,
                 color = Group)) +
  geom_smooth(aes(color = Group),
              formula = y ~ 1-exp(-k*x),
              method = "nls",
              method.args = list(start = c(k=start_values[1])),
              se = FALSE, data = function(x) subset(x, Group=="A")) + 
  geom_smooth(aes(color = Group),
              formula = y ~ 1-exp(-k*x),
              method = "nls",
              method.args = list(start = c(k=start_values[2])),
              se = FALSE, data = function(x) subset(x, Group=="B"))

enter image description here Rather than manually adding a layer for each group, you can also use mapply to create them for you

ggplot(data = df,
       aes(x = x,
           y = y)) +
  geom_point(aes(shape = Group,
                 color = Group)) +
  mapply(function(start, group) {
    geom_smooth(aes(color = Group),
          formula = y ~ 1-exp(-k*x),
          method = "nls",
          method.args = list(start = c(k=start)),
          se = FALSE, data = function(x) subset(x, Group==group))  
  }, start_values, c("A","B"))

Upvotes: 4

Related Questions