how to work backwards in a function in R - r

I was wondering if it would be possible to work backwards in a function in R in order to get a value for a variable that will output a known value.
For a simple example,
x<-5
afunction <- function(x,y) {
x*y
}
How can I get the value of y that will output a known value of say 15. That is, I want the the return of the function to be 3.
Is this possible?
Thank you.

If you are looking for the y value that makes afunction(x, y) equal 15, this is the same as finding the zeros of the following function:
g <- function(y) afunction(x, y) - 15
You can use uniroot to find zeros of a function:
uniroot(g, c(-100, 100))$root
# [1] 3
Note that you need to specify a range of y values for uniroot -- I've used [-100, 100] here.

Related

R code. write a floor function

I want to write a floor function in R, which returns a floating number to its nearest integer. So I tried the below function. It seems that it works if I assign a value to x and run the code inside the function, but it fails when I try to put everything in a function and call the function name later.
Does anyone know how to fix it?
Thanks!
> my_floor <- function(x) {
x <- x-0.5
as.integer(x)
return (x)
}
> y <- 3.1052255
> my_floor(y)
[1] 2.605225
No very sure what you are trying to do but if you simply want the input transformed to the nearest integer towards zero (i.e. floored as you your question goes), the one way to do it would be:
my_floor <- function(x) {
x <- trunc(x)
return (x)
}
This simply discards the non integer part of your input using R's trunc: which you might as well call directly i.e. trunc(y) will still give you the desired result. If you wish to use your function above "as is" then:
my_floor <- function(x) {
x <- x-0.5
x <- as.integer(x) #Store the result of this second step by reassigning x
return (x)
}

Vector with elements equal to a function evaluated at a, a+1,... b .in R

I have two integers a and b (with a less than b), as well as a function f(x). Is there a way of getting the vector
x<-(f(a), ..., f(b))
from R without having to explicitly having to write it out? as my a and b vary.
Thanks for your help.
You can try something like the following :
foo <- function(x) x+1
a <- 1
b <- 5
sapply(a:b, foo)
But note that if you need this kind of behavior, you should vectorize your function, ie make it accept a vector as argument instead of a single integer. In my previous example, the sapply is not needed at all : + is vectorized, so I can just do :
foo(a:b)

How do functions that simultaneously operate over vectors and their elements work in R?

Take the following example:
boltzmann <- function(x, t=0.1) { exp(x/t) / sum(exp(x/t)) }
z=rnorm(10,mean=1,sd=0.5)
exp(z[1]/t)/sum(exp(z/t))
[1] 0.0006599707
boltzmann(z)[1]
[1] 0.0006599707
It appears that exp in the boltzmann function operates over elements and vectors and knows when to do the right thing. Is the sum "unrolling" the input vector and applying the expression on the values? Can someone explain how this works in R?
Edit: Thank you for all of the comments, clarification, and patience with an R n00b. In summary, the reason this works was not immediately obvious to me coming from other languages. Take python for example. You would first compute the sum and then compute the value for each element in the vector.
denom = sum([exp(v / t) for v in x])
vals = [exp(v / t) / denom for v in x]
Whereas is R the sum(exp(x/t)) can be computed inline.
This is explained in An Introduction to R, Section 2.2: Vector arithmetic.
Vectors can be used in arithmetic expressions, in which case the
operations are performed element by element. Vectors occurring in the
same expression need not all be of the same length. If they are not,
the value of the expression is a vector with the same length as the
longest vector which occurs in the expression. Shorter vectors in the
expression are recycled as often as need be (perhaps fractionally)
until they match the length of the longest vector. In particular a
constant is simply repeated. So with the above assignments the command
x <- c(10.4, 5.6, 3.1, 6.4, 21.7)
y <- c(x, 0, x)
v <- 2*x + y + 1
generates a new vector v of length 11 constructed by adding together,
element by element, 2*x repeated 2.2 times, y repeated just once, and
1 repeated 11 times.
This might be clearer if you evaluated the numerator and the denominator separately:
x = rnorm(10,mean=1,sd=0.5)
t = .1
exp(x/t)
# [1] 1.845179e+05 6.679273e+03 4.379369e+06 1.852623e+06 9.960374e+02
# [6] 1.359676e+09 6.154045e+03 1.777027e+01 1.070003e+04 6.217397e+04
sum(exp(x/t))
# [1] 2984044296
Since the numerator is a vector of length 10, and the denominator is a vector of length 1, the division returns a vector of length 10.
Since you're interested in comparing this to Python, imagine the two following rules were added to Python (incidentally, these are similar to the usage of arrays in numpy):
If you divide a list by a number, it will divide all items in the list by the number:
[2, 4, 6, 8] / 2
# [1, 2, 3, 4]
The function exp in Python is "vectorized", which means that when it is applied to a list it will apply to each item in the list. However, sum still works the way you expect it to.
exp([1, 2, 3]) => [exp(1), exp(2), exp(3)]
In that case, imagine how this code would be evaluated in Python:
t = .1
x = [1, 2, 3, 4]
exp(x/t) / sum(exp(x/t))
It would follow the following simplifications, using those two simple rules:
exp([v / t for v in x]) / sum(exp([v / t for v in x]))
[exp(v / t) for v in x] / sum([exp(v / t) for v in x])
Now do you see how it knows the difference?
Vectorisation has several slightly different meanings in R.
It can mean accepting a vector input, transforming each element, and returning a vector (like exp does).
It can also mean accepting a vector input and calculating some summary statistic, then returning a scalar value (like mean does).
sum conforms to the second behaviour, but also has a third vectorisation behaviour, where it will create a summary statistic across inputs. Try sum(1, 2:3, 4:6), for example.

R curve() on expression involving vector

I'd like to plot a function of x, where x is applied to a vector. Anyway, easiest to give a trivial example:
var <- c(1,2,3)
curve(mean(var)+x)
curve(mean(var+x))
While the first one works, the second one gives errors:
'expr' did not evaluate to an object of length 'n' and
In var + x : longer object length is not a multiple of shorter object length
Basically I want to find the minimum of such a function: e.g.
optimize(function(x) mean(var+x), interval=c(0,1))
And then be able to visualise the result. While the optimize function works, I can't figure out how to get the curve() to work as well.. Thanks!
The function needs to be vectorized. That means, if it evaluates a vector it has to return a vector of the same length. If you pass any vector to mean the result is always a vector of length 1. Thus, mean is not vectorized. You can use Vectorize:
f <- Vectorize(function(x) mean(var+x))
curve(f,from=0, to=10)
This can be done in the general case using sapply:
curve(sapply(x, function(e) mean(var + e)))
In the specific example you give, mean(var) + x, is of course arithmetically equivalent to what you're looking for. Similar shortcuts might exist for whatever more complicated function you're working with.

How to pass vector to integrate function

I want to integrate a function fun_integrate that has a vector vec as an input parameter:
fun_integrate <- function(x, vec) {
y <- sum(x > vec)
dnorm(x) + y
}
#Works like a charm
fun_integrate(0, rnorm(100))
integrate(fun_integrate, upper = 3, lower = -3, vec = rnorm(100))
300.9973 with absolute error < 9.3e-07
Warning message:
In x > vec :
longer object length is not a multiple of shorter object length
As far as I can see, the problem is the following: integrate calls fun_integrate for a vector of x that it computes based on upper and lower. This vectorized call seems not to work with another vector being passed as an additional argument. What I want is that integrate calls fun_integrate for each x that it computes internally and compares that single x to the vector vec and I'm pretty sure my above code doesn't do that.
I know that I could implement an integration routine myself, i.e. compute nodes between lower and upper and evaluate the function on each node separately. But that wouldn't be my preferred solution.
Also note that I checked Vectorize, but this seems to apply to a different problem, namely that the function doesn't accept a vector for x. My problem is that I want an additional vector as an argument.
integrate(Vectorize(fun_integrate,vectorize.args='x'), upper = 3, lower = -3, vec = rnorm(100),subdivisions=10000)
304.2768 with absolute error < 0.013
#testing with an easier function
test<-function(x,y) {
sum(x-y)
}
test(1,c(0,0))
[1] 2
test(1:5,c(0,0))
[1] 15
Warning message:
In x - y :
longer object length is not a multiple of shorter object length
Vectorize(test,vectorize.args='x')(1:5,c(0,0))
[1] 2 4 6 8 10
#with y=c(0,0) this is f(x)=2x and the integral easy to solve
integrate(Vectorize(test,vectorize.args='x'),1,2,y=c(0,0))
3 with absolute error < 3.3e-14 #which is correct
Roland's answer looks good. Just wanted to point out that it's sum , not integrate that is throwing the warning message.
Rgames> xf <- 1:10
Rgames> vf <- 4:20
Rgames> sum(xf>vf)
[1] 0
Warning message:
In xf > vf :
longer object length is not a multiple of shorter object length
The fact that the answer you got is not the correct value is what suggests that integrate is not sending the x-vector you expected to your function.

Resources