Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Back solving a function or goal seek in R

Tags:

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.

like image 617
jgaecke Avatar asked Feb 18 '15 03:02

jgaecke


People also ask

What is the difference between Solver and Goal Seek feature?

Goal Seek: Determines the value that you need to enter in a single input cell to produce a result that you want in a dependent (formula) cell. Solver: Determines the values that you need to enter in multiple input cells to produce a result that you want.

Which method is behind Theexcel tool Goal Seek?

The Goal Seek[1] Excel function (often referred to as What-if-Analysis) is a method of solving for a desired output by changing an assumption that drives it. The function essentially uses a trial and error approach to back-solving the problem by plugging in guesses until it arrives at the answer.


1 Answers

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.

like image 51
jbaums Avatar answered Oct 02 '22 14:10

jbaums