# 在 R 中回求函数或目标值[英] Back solving a function or goal seek in R

### 问题描述

```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)
}
```

## 推荐答案

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

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

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

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

r将搜索[-1000，1000]，以尝试找到一个值x，以最大程度地降低myFunction(x) - 42010的绝对值.在这种情况下，它找到了123，myFunction(123)返回42010，so abs(myFunction(x) - 42010)返回0.

```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
```

### 问题描述

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.