3

我正在尝试解决这个等式:((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) =1

有没有办法用 R 做到这一点?

尝试使用不正确的解决方案:

library(Ryacas)
eq <- "((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 "
# simplify the equation:
library(glue)
yac_str(glue("Simplify({eq})"))
library(evaluate)
evaluate(eq,list(x=c(0,1,10,100,-100)))

evaluate()只返回方程:

"((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 " 

方程的答案是 -2004200

4

5 回答 5

2

1) Ryacas使用如下所示的Ryacas包。solve(感谢@mikldk 对最后一行的改进。)

library(Ryacas)
eq <- "((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 "  # from question

res <- solve(ysym(eq), "x")
as_r(y_rmvars(res))  # extract and convert to R
## [1] -2004200

如果eq其中有 R 变量,这里在h中引用eq2,然后用于eval评估结果。

h <- 2300
eq2 <- "((h+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 "  # from question
res2 <- solve(ysym(eq2), "x")
eval(as_r(y_rmvars(res2)))
## [1] -2004200

2) Ryacas0eq从上面与Ryacas0包一起使用:

library(Ryacas0)

res <- Solve(eq, "x")
eval(Expr(res)[[1:3]]) # convert to R
## [1] -2004200

3a) 基数 R鉴于这是一个线性方程和以下的解,其中 A 是斜率,B 是截距:

A * x + B = 0

x = - B / A

如果我们x用虚数替换,1i然后将 rhs 移动到 lhs,我们就有了,B并且A是该表达式的实部和虚部。不使用任何包。

r <- eval(parse(text = sub("==", "-", eq)), list(x = 1i))
-Re(r) / Im(r)
## [1] -2004200

3b)如果我们将 rhs 移动到 lhs 则 B 在 x=0 处等于它,并且 A 等于 x 的导数,因此另一个基本 R 解决方案将是:

e <- parse(text = sub("==", "-", eq))
- eval(e, list(x = 0)) / eval(D(e, "x"))
## [1] -200420
于 2020-12-20T21:19:55.240 回答
2

听起来您想要Solve()x 而不仅仅是简化 ... ?下面的代码求解方程,x==从解中去掉 ,并对表达式求值:

eq2 <- gsub("x==","",yac_str(glue("Solve({eq},x)")))
[1] "{(-0.80168e6)/0.4}"
eval(parse(text=eq2))
[1] -2004200
于 2020-12-20T19:40:56.540 回答
1

如果你想要快速的东西:rootSolve图书馆是你的首选。

library(rootSolve)
func_ <- function(x) ((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400)-1
uniroot.all(func_, c(-1e9, 1e9))
[1] -2004200

请注意,大多数情况下减少间隔会更好。

于 2020-12-20T19:48:03.937 回答
1

这是一个基本的 R 解决方案。
将方程改写为函数形式,curve用于得到函数符号不同的两个端点并投入uniroot工作。

f <- function(x) ((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) - 1
curve(f, -1e7, 1)
uniroot(f, c(-1e7, 1))
#$root
#[1] -2004200
#
#$f.root
#[1] 0
#
#$iter
#[1] 1
#
#$init.it
#[1] NA
#
#$estim.prec
#[1] 7995800

在对该问题的评论中进行讨论之后,这是一个通用解决方案。现在要找到其根的函数接受一个参数params,以便传递租金、工资、工人数量、价格、单位成本和资本成本的值。此参数必须是命名列表。

f <- function(x, K = 1, params) {
  A <- with(params, rent + salary*workers)
  with(params, (A + (x + A)*capitalcost)/(price - unitcost) - K)
}

params <- list(
  rent = 2300, 
  salary = 1900, 
  workers = 1, 
  price = 600, 
  unitcost = 400, 
  capitalcost = 0.002
)
curve(f(x, params = params), -1e7, 1)
uniroot(f, c(-1e7, 1), params = params)
于 2020-12-20T19:44:11.483 回答
0

如果您将保持相同的结构,那么在 Base R 中,您可以执行以下操作:

solveX <- function(eq){
  U <- function(x)abs(eval(parse(text = sub("=+","-", eq)), list(x=x)))
  optim(0, U, method = "L-BFGS-B")$par
}
eq <- "((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 "
solveX(eq)
[1] -2004200
于 2020-12-20T20:02:33.687 回答