在Excel中,存在一个解决此问题的简单方法 - >求解。我现在想在R中执行相同的任务。首先我的数据:
library(data.table)
date <- seq(2015, 2024, 1)
t <- seq(1,10,1)
balance <- c(33, 28, 23, 19, 17, 14, 12, 9, 8, 7)
mydata <- data.table(cbind(date, t, balance))
我现在想在“平衡”上只用一个参数(估计线)拟合非线性线。估计的行定义如下:
t[2015;2024]= balance(t=2015)*(1-x)^t
的估计输出。因此我们知道平衡,我们知道。我正在寻找一个常数x,它可以最大限度地减少观察到的平衡误差的平方和 - 所有10
年的估计平衡。
有一种简单的估算方法吗?一种可与Excel中的Solver相媲美的方法吗?
答案 0 :(得分:0)
虽然我同意David Arenburg,并使用nloptr
进行几乎所有优化,但为了保持简单,我们可以使用base optim
和method = Brent(因为这是一个参数问题)
这是您的数据
library(data.table)
date <- seq(2015, 2024, 1)
t <- seq(1,10,1)
balance <- c(33, 28, 23, 19, 17, 14, 12, 9, 8, 7)
mydata <- data.table(cbind(date, t, balance))
现在我们需要创建一个函数,它将返回给定输入的平方误差:
error_f <- function(x, mydata){
estimated_bal <- mydata$balance[1] * (1 - x) ^ mydata$t
return(sum((estimated_bal - mydata$balance)^2))
}
现在,只需运行optim
(您也可以使用optimize
,因为这是一个单变量的问题)
> Z <- optim(par = 2, fn = error_f, lower = -1e6, upper = 1e6, method = 'Brent', mydata = mydata)
> Z
$par
[1] 0.1304993
$value
[1] 36.55443
$counts
function gradient
NA NA
$convergence
[1] 0
$message
NULL
结果:
mydata$balance[1] * (1 - Z$par) ^ mydata$t
[1] 28.693524 24.949040 21.693208 18.862261 16.400749 14.260463 12.399483 10.781360 9.374400 8.151048
答案 1 :(得分:0)
func = function(x) 33*((1-x)^t)
costFunc = function(x) sum((func(x)-balance)**2)
res = optim(0, costFunc)
您想要的x存储在res$par
:
> res$par
[1] 0.1305176
对x
的某些值进行虚拟化并与balance
进行比较:
library(ggplot2)
library(tidyr)
mydata[, c("func1", "func2","func3","func4"):=list(func(0.2), func(0.15),func(0.1), func(0.05))]
dt = gather(mydata, var, value, balance:func4)
ggplot() +
geom_line(aes(x=t, y=value, color=var),subset(dt, var!="balance")) +
geom_point(aes(x=t, y=value),subset(dt, var=="balance"))
答案 2 :(得分:0)
只需使用nls
:
fit <- nls(balance ~ balance[t == 1] * (1-x)^t, data = mydata, start = list(x = 0))
summary(fit)
#Formula: balance ~ balance[t == 1] * (1 - x)^t
#
#Parameters:
# Estimate Std. Error t value Pr(>|t|)
#x 0.130499 0.007404 17.63 2.76e-08 ***
#---
#Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
#Residual standard error: 2.015 on 9 degrees of freedom
#
#Number of iterations to convergence: 6
#Achieved convergence tolerance: 6.426e-07
plot(balance ~ t, data = mydata)
lines(mydata$t, fitted(fit))