繁体   English   中英

从 2 个点在 R 中创建指数函数

[英]Create exponential function in R from 2 points

当只给出直线通过的 2 个点时,我想在 R 中创建一个指数函数。 我想使用基本的 f(x) = ab^x 格式。 我了解如何通过创建两个方程然后分别求解 b 和 a 来手动执行此操作,但是我在用 R 进行编码时遇到了问题。例如,当我尝试为一个变量分配另一个变量时,我在此过程的第一步中获取“找不到对象错误”。

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

我明白为什么我会收到这个错误,但我不知道解决方法。

我可以仅使用前 2 个点来创建指数模型,但系数与实际数据值相差甚远。

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

(Intercept)        df$x 
300.1250000   0.2857143

根据数据截距应该更接近66(y = 66,当x = 0.02时)

我最终希望能够使用此函数在一条线上取两个点,然后绘制这条线并根据其他 x 输入(即 c(0,1,2,3,4))生成值,但是我我很早就遇到了麻烦。

编辑:我不一定要尝试从 2 点创建模型并期待一个很好的预测。 我正在尝试确定通过两点的直线的指数函数,类似于this ,但用 R 编码。(这条线不会是完美的,因为它是由数据组成的。)

您没有获得所需截距的原因是数据框中的前两个点与其他点不在同一指数曲线上。 我们可以通过对x绘制log(y)来看到这一点:

plot(x, log(y))

在此处输入图片说明

现在让我们只使用前两个点(最右边的两个点)绘制回归

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

在此处输入图片说明

并为其他 5 个点添加一条线:

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

在此处输入图片说明

你可以看到,如果我们只使用两个点,那么梯度和截距对任何与完美指数曲线的实验偏差都非常敏感。

这里有一个更大的观点,那就是如果您试图仅使用两个实验数据点进行预测,那么您的预测将不会非常准确。

相反,如果我们使用所有的点,我们就可以对整个关系进行合理的预测:

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

在此处输入图片说明

截距的数值预测更接近你的预期:

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

编辑

要从两点“手动”计算方程,您需要取 y 值的对数,然后您可以通过执行以下操作来计算两点之间对数线的梯度:

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

并且您可以通过求解y = gradient * x + intercept来获得截距,即:

intercept <- log(y1) - gradient * x1

然后,您可以对梯度和截距求幂以找到原始线的系数。 例如,使用这个函数:

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 = "")
}

我们得到

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

如果我们想在任意两点之间画一条指数曲线,我们可以这样做:

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")

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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