Given a vector (actually a list) of functions:
fs = c(sin, cos, tan)
and a vector of values:
xs = c(.1, .3, .5)
Is there a better/neater/faster/stronger way of computing fs[[i]](xs[i]) for each vector element:
vapply(1:3, FUN.VALUE = 1 ,function(i){fs[[i]](xs[i])})
[1] 0.09983342 0.95533649 0.54630249
Or am I missing a fapply function somewhere? The functions will always be functions of a single scalar value and returning a single scalar value.
Nice and simple:
mapply(function(fun, x) fun(x), fs, xs)
But I agree with #flodel. I was also looking for a base function for function(fun, ...) fun(...) and was surprised that there doesn't seem to be one. On the other hand I've never needed it, so far.
Here's an alternative whose main advantage over the suggestions so far is that it doesn't require that an anonymous function be defined.
mapply(do.call, fs, lapply(xs, list))
# [1] 0.09983342 0.95533649 0.54630249
Related
I have a function of two arguments foo(a,b). As an input of this function, I was to use every row of the output of combinations(10,2) from the gtools library. I've tried to get it to work with mapply and I really had high hopes for apply(combinations(10,2),1,foo), but everything that I've attempted throws the error "argument "b" is missing, with no default". How can I correct this without storing combinations(10,2) in memory and dividing it up? I suspect that I'm missing a trick with Vectorize.
For a simple reproducible example, use beta(a,b) in place of foo(a,b).
What I very specifically do not want to do is anything like:
a<-combinations(10,2)
mapply(foo,a[,1],a[,2])
because I do not want to store combinations(10,2) in memory.
Here we can use do.call with mapply or Map
do.call(mapply, c(FUN = foo, asplit(combinations(10, 2), 2)))
Or with Map (returns a list)
do.call(Map, c(f = foo, asplit(combinations(10, 2), 2)))
As a reproducible example, can use beta
do.call(Map, c(f = beta, asplit(combinations(10, 2), 2)))
I have list of functions which also contains one user defined function:
> fun <- function(x) {x}
> funs <- c(median, mean, fun)
Is it possible to get function names as strings from this list? My only workaround so far was to create vector which contains function names as strings:
> fun.names <- c("median", "mean", "fun")
When I want to get variable name I use to do this trick (if this is not correct correct me please) but as you can see it only work for one variable not for list:
> as.character(substitute(mean))
[1] "mean"
> as.character(substitute(funs))
[1] "funs"
Is there something that will work also for list? Is there any difference if list contains functions or data types?
EDIT:
I need to pass this list of functions (plus another data) to another function. Then those functions from list will be applied to dataset. Function names are needed because if there are several functions passed in list I want to being able to determine which function was applied. So far I've been using this:
window.size <- c(1,2,3)
combinations <- expand.grid(window.size, c(median, mean))
combinations <- cbind(combinations, rep(c("median","mean"), each = length(window.size)))
Generally speaking, this is not possible. Consider this definition of funs:
funs <- c(median,mean,function(x) x);
In this case, there's no name associated with the user-defined function at all. There's no rule in R that says all functions must be bound to a name at any point in time.
If you want to start making some assumptions about whether and where all such lambdas are defined, then possibilities open up.
One idea is to search the closure environment of each function for an entry that matches (identically) to the function itself, and then use that name. This will incur a performance penalty due to the comparison work, but may be tolerable if you don't have to run it repetitively:
getFunNameFromClosure <- function(fun) names(which(do.call(c,eapply(environment(fun),identical,fun)))[1L]);
Demo:
fun <- function(x) x;
funs <- c(median,mean,fun);
sapply(funs,getFunNameFromClosure);
## [1] "median" "mean" "fun"
Caveats:
1: As explained earlier, this will not work on functions that were never bound to a name. Furthermore, it will not work on functions whose closure environment does not contain a binding to the function. This could happen if the function was bound to a name in a different environment than its closure (via a return value, superassignment, or assign() call) or if its closure environment was explicitly changed.
2: It is possible to bind a function to multiple names. Thus, the name you get as a result of the eapply() search may not be the one you expect. Here's a good demonstration of this:
getFunNameFromClosure(ls); ## gets wrong name
## [1] "objects"
identical(ls,objects); ## this is why
## [1] TRUE
Here is a hacky approach:
funs <- list(median, mean)
fun_names = sapply(funs, function(x) {
s = as.character(deparse(eval(x)))[[2]]
gsub('UseMethod\\(|[[:punct:]]', '', s)
})
names(funs) <- fun_names
funs
$median
function (x, na.rm = FALSE)
UseMethod("median")
<bytecode: 0x103252878>
<environment: namespace:stats>
$mean
function (x, ...)
UseMethod("mean")
<bytecode: 0x103ea11b8>
<environment: namespace:base>
combinations <- expand.grid(window.size, fun_names, c(median, mean))
Easier to ask by example. If I have a function
fn <- function(x) {
...
return(c(a,b,c))
}
and I wish to maximize (or minimize) with respect to a, but also get the values of b and c at the optimal value.
Of course I can use fn2 <- function(x) fn(x)[1] to determine the optimal value, then call the function again, but I wonder if there is a smarter way of doing this.
optim needs the return value to be a scalar. The documentation says so
fn: A function to be minimized (or maximized), with first
argument the vector of parameters over which minimization is
to take place. It should return a scalar result.
You could write the values of interest to a global variable inside your function though. This isn't necessarily best practice but it could work.
f <- function(x){
.vals <<- c(x, x+1)
x^2
}
optim(1, f)
then after we can look at what is stored in .vals
> .vals
[1] 9.765625e-05 1.000098e+00
The problem is quite simple yet I can't find the answer.
I have myfun <- function(x, y). How can I sapply this function over a list of y?
To apply over x I would do this
iterables <- 1:10
sapply(iterables, myfun, y)
But I want the iterables to be y instead.
You have several options - e.g. one mentioned by sgibb which relies on how R interprets function arguments, i.e. that myfun(y, x = x) is the same as myfun(x, y).
I prefer creating anonymous functions since it's easier to understand what's happening:
sapply(iterables, function(iter) myfun(x, iter))
The following function is used to multiply a sequence 1:x by y
f1<-function(x,y){return (lapply(1:x, function(a,b) b*a, b=y))}
Looks like a is used to represent the element in the sequence 1:x, but I do not know how to understand this parameter passing mechanism. In other OO languages, like Java or C++, there have call by reference or call by value.
Short answer: R is call by value. Long answer: it can do both.
Call By Value, Lazy Evaluation, and Scoping
You'll want to read through: the R language definition for more details.
R mostly uses call by value but this is complicated by its lazy evaluation:
So you can have a function:
f <- function(x, y) {
x * 3
}
If you pass in two big matrixes to x and y, only x will be copied into the callee environment of f, because y is never used.
But you can also access variables in parent environments of f:
y <- 5
f <- function(x) {
x * y
}
f(3) # 15
Or even:
y <- 5
f <- function() {
x <- 3
g <- function() {
x * y
}
}
f() # returns function g()
f()() # returns 15
Call By Reference
There are two ways for doing call by reference in R that I know of.
One is by using Reference Classes, one of the three object oriented paradigms of R (see also: Advanced R programming: Object Oriented Field Guide)
The other is to use the bigmemory and bigmatrix packages (see The bigmemory project). This allows you to create matrices in memory (underlying data is stored in C), returning a pointer to the R session. This allows you to do fun things like accessing the same matrix from multiple R sessions.
To multiply a vector x by a constant y just do
x * y
The (some prefix)apply functions works very similar to each other, you want to map a function to every element of your vector, list, matrix and so on:
x = 1:10
x.squared = sapply(x, function(elem)elem * elem)
print(x.squared)
[1] 1 4 9 16 25 36 49 64 81 100
It gets better with matrices and data frames because you can now apply a function over all rows or columns, and collect the output. Like this:
m = matrix(1:9, ncol = 3)
# The 1 below means apply over rows, 2 would mean apply over cols
row.sums = apply(m, 1, function(some.row) sum(some.row))
print(row.sums)
[1] 12 15 18
If you're looking for a simple way to multiply a sequence by a constant, definitely use #Fernando's answer or something similar. I'm assuming you're just trying to determine how parameters are being passed in this code.
lapply calls its second argument (in your case function(a, b) b*a) with each of the values of its first argument 1, 2, ..., x. Those values will be passed as the first parameter to the second argument (so, in your case, they will be argument a).
Any additional parameters to lapply after the first two, in your case b=y, are passed to the function by name. So if you called your inner function fxn, then your invocation of lapply is making calls like fxn(1, b=4), fxn(2, b=4), .... The parameters are passed by value.
You should read the help of lapply to understand how it works. Read this excellent answer to get and a good explanation of different xxpply family functions.
From the help of laapply:
lapply(X, FUN, ...)
Here FUN is applied to each elementof X and ... refer to:
... optional arguments to FUN.
Since FUN has an optional argument b, We replace the ... by , b=y.
You can see it as a syntax sugar and to emphasize the fact that argument b is optional comparing to argument a. If the 2 arguments are symmetric maybe it is better to use mapply.