Using outer() with a multivariable function - r

Suppose you have a function f<- function(x,y,z) { ... }. How would you go about passing a constant to one argument, but letting the other ones vary? In other words, I would like to do something like this:
output <- outer(x,y,f(x,y,z=2))
This code doesn't evaluate, but is there a way to do this?

outer(x, y, f, z=2)
The arguments after the function are additional arguments to it, see ... in ?outer. This syntax is very common in R, the whole apply family works the same for instance.
Update:
I can't tell exactly what you want to accomplish in your follow up question, but think a solution on this form is probably what you should use.
outer(sigma_int, theta_int, function(s,t)
dmvnorm(y, rep(0, n), y_mat(n, lambda, t, s)))
This calculates a variance matrix for each combination of the values in sigma_int and theta_int, uses that matrix to define a dennsity and evaluates it in the point(s) defined in y. I haven't been able to test it though since I don't know the types and dimensions of the variables involved.

outer (along with the apply family of functions and others) will pass along extra arguments to the functions which they call. However, if you are dealing with a case where this is not supported (optim being one example), then you can use the more general approach of currying. To curry a function is to create a new function which has (some of) the variables fixed and therefore has fewer parameters.
library("functional")
output <- outer(x,y,Curry(f,z=2))

Related

Function taking Vectors and Scalars

I have a function that takes a vector
function foo(x::Vector{Int64})
x
end
How can I make it work also for scalars (i.e. turn them into one-element vectors)?
I know that I can do this:
foo(x::Int64) = foo([x])
but this stops being cool when there are more arguments, because you're writing multiple methods to achieve only one thing.
I think I something like foo(x::Union{Int64, Vector{Int64}}), but I don't know where or how it works or if it is the right thing to do.
Can anyone help?
You can make a helper function which either converts or does nothing. Then the main function can accept any combination:
_vec(x::Number) = [x]
_vec(x::AbstractVector) = x
function f(x, y, z) # could specify ::Union{Number, AbstractVector}
xv = _vec(x)
yv = _vec(y)
...
end
The ... could do the actual work, or could call f(xv, yv, zv) where another method f(x::AbstractVector, y::AbstractVector, z::AbstractVector) does the work --- whichever seems cleaner.
The main time this comes up is if the version of your function for vectors does the same thing for all of it's elements. In this case, what you want to do is define f(x::Int), and use broadcasting f.([1,2,3]) for the vector case.

What is the recommended pattern to design a function that can implement multiple algorithms for S4 class in R?

I have an object of class S4 "MyOb" and a generic function "MyFun". I would like to implement multiple different algorithms for MyFun to process MyOb and be able to select the algorithm I want by specifying the "type" in the generic function. Type would be an argument of MyFun and would be just a character (string): "Algo1", "Algo2"...
However, each algorithm would require different arguments. I have started has indicated in the code below but then I am not sure how to continue, should I have a switch in the setMethod function that redirect to other separate functions ?
setGeneric("MyFun", function(x, type, ...) standardGeneric("MyFun"))
setMethod("MyFun", c("MyOb", "character"), function(x, type, ...){
switch()??? #to Algo1, Algo2, ....
})
Algo1<-function(x, M, N){ #blabla }
Algo2<-function(x, F, G, H){ #blablabla }
Ideally, I like to end up with something like the function baseline in the baseline R package, with
MyFun.Algo1, MyFun.Algo2 being the different function and MyFun the generic one...
I have been looking for this type of pattern but could not find any tutorial...
Any hint, advice, recommendation would be appreciated!
Thank you very much!
Firstly, you probably want to only have x as the signature of your function (you don't want a different method based on the class of type, for example). So you should start with
setGeneric("MyFun", function(x, type, ...) standardGeneric("MyFun"), signature="x")
(you don't even have to have type amongst the arguments to the generic if you don't want to — it depends whether it would be used for other classes of input.)
If you need different other arguments for later algorithms, that is fine. The ... sorts this out for you. So if you have your two algorithms
Algo1<-function(x, M, N){ #blabla }
Algo2<-function(x, F, G, H){ #blablabla }
then these will get called correctly when you call
MyFun(x,type="Algo1",M=1,N=2) ## dispatched Algo1 with M=1 and N=2
MyFun(x,type="Algo2",F=3,G=4,H=-2.7) ## dispatches Algo2 with F, G and H
The recommended way to write the MyFun method is as follows (you were right with your intuition to use switch):
setMethod("MyFun",signature(x="MyObj"), function(x,type=c("Algo1","Algo2"),...){
type <- match.arg(type)
switch(type,
Algo1=Algo1(x,...),
Algo2=Algo2(x,...),
stop("unknown algorithm")
)
})
It would probably be wise to make sure that Algo1 and Algo2 do some argument checking to make sure they are receiving the arguments they expect. This is good programming practice in general, but perhaps more important here.
If you haven't come across match.arg before, it's the recommended way of ensuring an argument matches one of a defined set of values. It uses the default argument as the list of allowed values.

Function doesn't change value (R)

I have written a function that takes two arguments, a number between 0:16 and a vector which contains four parameter values.
The output of the function does change if I change the parameters in the vector, but it does not change if I change the number between 0:16.
I can add, that the function I'm having troubles with, includes another function (called 'pi') which takes the same arguments.
I have checked that the 'pi' function does actually change values if I change the value from 0:16 (and it does also change if I change the values of the parameters).
Firstly, here is my code;
pterm_ny <- function(x, theta){
(1-sum(theta[1:2]))*(theta[4]^(x))*exp((-1)*theta[4])/pi(x, theta)
}
pi <- function(x, theta){
theta[1]*1*(x==0)+theta[2]*(theta[3]^(x))*exp((-1)*(theta[3]))+(1-
sum(theta[1:2]))*(theta[4]^(x))*exp((-1)*(theta[4]))
}
Which returns 0.75 for pterm_ny(i,c(0.2,0.2,2,2)), were i = 1,...,16 and 0.2634 for i = 0, which tells me that the indicator function part in 'pi' does work.
With respect to raising a number to a certain power, I have been told that one should wrap the wished number in a 'I', as an example it would be like;
x^I(2)
I have tried to do that in my code, but that didn't help either.
I can't remember the argument for doing it, but I expect that it's to ensure that the number in parentheses is interpreted as an integer.
My end goal is to get 17 different values of the 'pterm' and to accomplish that, I was thinking of using the sapply function like this;
sapply(c(0:16),pterm_ny,theta = c(0.2,0.2,2,2))
I really hope that someone can point out what I'm missing here.
In advance, thank you!
You have a theta[4]^x term both in your main expression and in your pi() function; these are cancelling out, leaving the result invariant to changes in x ...
Also:
you might want to avoid using pi as your function name, as it's also a built-in variable (3.14159...) - this can sometimes cause confusion
the advice about using the "as is" function I() to protect powers is only relevant within formulas, e.g. as used in lm() (linear regression). (It would be used as I(x^2), not x^I(2)

R optim same function for fn and gr

I would like to use optim() to optimize a cost function (fn argument), and I will be providing a gradient (gr argument). I can write separate functions for fn and gr. However, they have a lot of code in common and I don't want the optimizer to waste time repeating those calculations. So is it possible to provide one function that computes both the cost and the gradient? If so, what would be the calling syntax to optim()?
As an example, suppose the function I want to minimize is
cost <- function(x) {
x*exp(x)
}
Obviously, this is not the function I'm trying to minimize. That's too complicated to list here, but the example serves to illustrate the issue. Now, the gradient would be
grad <- function(x) {
(x+1)*exp(x)
}
So as you can see, the two functions, if called separately, would repeat some of the work (in this case, the exponential function). However, since optim() takes two separate arguments (fn and gr), it appears there is no way to avoid this inefficiency, unless there is a way to define a function like
costAndGrad <- function(x) {
ex <- exp(x)
list(cost=x*ex, grad=(x+1)*ex)
}
and then pass that function to optim(), which would need to know how to extract the cost and gradient.
Hope that explains the problem. Like I said my function is much more complicated, but the idea is the same: there is considerable code that goes into both calculations (cost and gradient), which I don't want to repeat unnecessarily.
By the way, I am an R novice, so there might be something simple that I'm missing!
Thanks very much
The nlm function does optimization and it expects the gradient information to be returned as an attribute to the value returned as the original function value. That is similar to what you show above. See the examples in the help for nlm.

How to specify FUN used in by( ) or related apply( ) functions

In a by() function, I will use cor (correlation) to be the FUN there. However, I'd like to setup use="complete.obs" too.
I don't know how to pass this argument in the FUN = cor part.
For example,
by(data, INDICES=list(data$Age), FUN=cor)
probably
by(data, INDICES=list(data$Age), FUN=cor, use = "complete.obs")
will work.
the arguments to by are passed to FUN.
If you start looking around at various R help files for functions like by, you may start to notice a curious 'argument' popping up over and over again: .... You're going to see an ellipsis listed along with all the other arguments to a function.
This is actually an argument itself. It will collect any other arguments you pass and hand them off to subsequent functions called later. The documentation will usually tell you what function these arguments will be handed to.
In this case, in ?by we see this:
... further arguments to FUN.
This means that any other arguments you pass to by that don't match the ones listed will be handed off to the function you pass to FUN.
Another common instance can be found in plot, where the documentation only lists two specific arguments, x and y. Then there's the ... which gathers up anything else you pass to plot and hands it off to methods or to par to set graphical parameter settings.
So in #kohske's example, use = "complete.obs" will be automatically passed on the cor, since it doesn't match any of the other arguments for by.
#kohske and #joran give equivalent answers showing built in features of by (which are also present in apply and the entire plyr family) for passing additional arguments to the supplied function since this is a common application/problem. #Tomas also shows another way to specify an anonymous function which is just a function that calls the "real" function with certain parameters fixed. Fixing parameters to a function call (to effectively make a function with fewer arguments) is a common approach, especially in functional approaches to programming; in that context it is called currying or partial application.
library("functional")
by(data, INDICES=list(data$Age), FUN=Curry(cor, use = "complete.obs"))
This approach can be used when one function does not use ... to "pass along" arguments, and you want to indicate the only reason that an anonymous function is needed is to specify certain arguments.
In general, you have 2 possibilities:
1) specify the arguments in the calling function (tapply() or by() in this case). This also works even if the key argument to fun() is not the first one:
fun <- function(arg1, arg2, arg3) { ... } # just to see how fun() looks like
tapply(var1, var2, fun, arg1 = something, arg3 = something2)
# arg2 will be filled by tapply
2) you may write your wrapper function (sometimes this is needed):
tapply(var1, var2, function (x) { fun(something, x, something2) })

Resources