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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With