简体   繁体   中英

Back solving a function or goal seek in R

I'm trying to learn my way around R and I need a little help. Below is a little sample of the kind of problem I am working on.

myFunction <- function(price1) {
  prices <- c(1:50)
  prices[1] <- price1
  recursiveA <- vector(length = 51)
  recursiveA[1] <- 100
  for (i in 1:50) {
    recursiveA[i+1] <- 30*prices[i] + recursiveA[i]
  }
  target <- recursiveA[51]
  return(target)
}

What I want to do is create a new function that will find the price1 value needed to yield a target value. For example in this new function I would be able to set 47320 as a parameter and it would return 300 . In the first function, myFunction , a value of 300 returns a value of 47320 .

How can I write a function in R to do this? Is there an existing function in R? I see through my Googling and searching on this site, a lot of people recommend the uniroot() function or optimize() . I can't figure out how to use that for something other than algebraic quadratics.

If it helps, I know that in excel I can solve this easily by using the goal seek tool. You can set a desired output and it finds the needed input from the formula(s) you define.

Please let me know if anything's unclear and I will try my best to explain further.

Any help is much appreciated. Thank you.

You don't actually need a recursive function here.

Here's a vectorised approach:

f <- function(x) tail(cumsum(c(100, 30*c(x, 2:50))), 1)
f(123)
# 42010

And to reverse the operation:

anti_f <- function(x) (x - 30*50*51/2 + 30 - 100)/30
anti_f(42010)
# 123

Of course, this is less helpful when you actually do need to recurse. My point is just that you should look for opportunities to vectorise when possible.


If you want to do this with optimize , you can do:

f <- function(x) abs(myFunction(x) - 42010) 
optimize(f, lower=-1000, upper=1000)

# $minimum
# [1] 123
# 
# $objective
# [1] 2.512278e-05

R will search [-1000, 1000] in an attempt to find a value, x , that minimises the absolute value of myFunction(x) - 42010 . In this case, it finds 123 , for which myFunction(123) returns 42010 and so abs(myFunction(x) - 42010) returns 0 .

If you want to wrap this in a function, you can do:

unfunction <- function(x, lower, upper) {
  optimize(function(y) abs(myFunction(y) - x), lower=lower, upper=upper)
}

unfunction(42010, -1000, 1000)

# $minimum
# [1] 123
# 
# $objective
# [1] 2.512278e-05

unfunction(47320, -1000, 1000)

# $minimum
# [1] 300
# 
# $objective
# [1] 0.0002383182

In our function unfunction , lower and upper specify the space to be searched.

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