简体   繁体   中英

Create exponential function in R from 2 points

I would like to create an exponential function in R when only 2 points that the line passes through are given. I'd like to use the basic f(x) = ab^x format. I understand how to do this by hand, by creating two equations and then separately solving for b and a, but I'm having issues coding this in R. For example, when I try to assign a variable with another variable in it, I get the "object not found error" on the first step of this process.

x <- c(4, 3, 1.8, 1.1, .6, .3, .02) 
y <- c(2, 7, 16, 27, 40, 51, 66)  
df <- data.frame(x,y)
a <- df$y[1]/b^df$x[1]

Error: object 'b' not found

I understand why I'm getting this error, but I don't know a way around it.

I could create an exponential model by only using the first 2 the points, but the coefficients are no where close to the actual data values.

expmod <- lm(log(df$y[1:2])~df$x[1:2])
exp(expmod$coefficients)

(Intercept)        df$x 
300.1250000   0.2857143

The intercept should be closer to 66 based on the data (y = 66, when x = 0.02)

I eventually want to be able to use this function to take two points on a line and then both plot the line and produce values based on other x inputs (ie c(0,1,2,3,4)), but I'm running into trouble early on.

edit: I am not necessarily trying to create a model from 2 points and expecting a great prediction. I am trying do determine the exponential function of a line that passes through two points, similar to this , but coded in R. (The line won't be perfect, because it's made up data.)

The reason you are not getting the intercept you want is that the first two points in your data frame are not on the same exponential curve as the other points. We can see this by plotting log(y) against x :

plot(x, log(y))

在此处输入图片说明

Now let's draw the regression using only your first two points (the two rightmost points)

abline(lm(log(y) ~ x, data = df[1:2, ]), col = "red")

在此处输入图片说明

and add a line for the other 5 points:

abline(lm(log(y) ~ x, data = df[-c(1:2), ]), col = "blue")

在此处输入图片说明

You can see that if we only use two points, then the gradient and intercept are very sensitive to any experimental deviations from a perfect exponential curve.

There is a larger point here, which is that if you are trying to make predictions using only two experimental data points, then your predictions will not be very accurate.

Conversely, if we use all the points, we get a reasonable prediction for the relationship as a whole:

plot(x, y)
lines(new_frame$x, new_frame$y, col = "red")

在此处输入图片说明

And the numerical prediction for the intercept is closer to your expectations:

exp(lm(log(y) ~ x, data = df)$coef)
#> (Intercept)           x 
#>  68.2345853   0.4335491 

EDIT

To calculate the equation "manually" from two points, you need to take the log of the y values, then you can calculate the gradient of the log line between two points by doing:

gradient <- (log(y2) - log(y1)) / (x2 - x1)

and you can get the intercept by solving y = gradient * x + intercept for intercept , that is:

intercept <- log(y1) - gradient * x1

you can then exponentiate the gradient and the intercept to find the coefficients of your original line. For example, using this function:

exp_line <- function(x1, x2, y1, y2) {
  gradient  <- (log(y2) - log(y1)) / (x2 - x1)
  intercept <- log(y1) - gradient * x1
  cat("y = ", exp(gradient), "^x * ", exp(intercept), "\n", sep = "")
}

We get

exp_line(x[1], x[2], y[1], y[2])
#> y = 0.2857143^x * 300.125

exp_line(x[4], x[5], y[4], y[5])
#> y = 0.455625^x * 64.10553

And if we want to draw an exponential curve between any two points, we can do the following:

draw_exp_line <- function(x1, x2, y1, y2, col) {
  gradient  <- (log(y2) - log(y1)) / (x2 - x1)
  intercept <- log(y1) - gradient * x1
  x <- seq(0, 5, 0.1)
  lines(x, exp(gradient)^x * exp(intercept), col = col)
}

plot(x, y)
draw_exp_line(x[2], x[1], y[2], y[1], "red")

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM