I want to use the rollapply
function with various combinations of the width
, by
and FUN
arguments ( width
and by
must have the same value). I inspired here and created the following code that works, but it has nothing to do with rollapply
so far, it just demonstrates how to pass a few arguments to a function inside apply
:
> dframe <- expand.grid(c(1,2,3), c(1,2,3)) > testFunc <- function(a, b) a^2 + b > apply(dframe, 1, function(x) testFunc(x[1], x[2])) [1] 2 5 10 3 6 11 4 7 12 > apply(dframe, 1, function(x) x[1]^2 + x[2]) [1] 2 5 10 3 6 11 4 7 12 > apply(dframe, 1, function(x) (x[1]^2 + x[2])) [1] 2 5 10 3 6 11 4 7 12 > apply(dframe, 1, function(x) {x[1]^2 + x[2]}) [1] 2 5 10 3 6 11 4 7 12
My final solution is here, but this does not work:
> dframe <- expand.grid(c(1,2,3), c(median, mean)) > testFunc <- function(a, b) rollapply(mtcars, width = a, by = a, FUN = b, align="left") > apply(dframe, 1, function(x) testFunc(x[1], x[2])) Error in get(as.character(FUN), mode = "function", envir = envir) : object 'b' of mode 'function' was not found > apply(dframe, 1, function(x) rollapply(mtcars, width = x[1], by = x[1], FUN = x[2], align="left")) Error in match.fun(FUN) : 'x[2]' is not a function, character or symbol
When I call testFunc
, everything works fine, so I think the problem is that apply
cannot somehow collect the results:
> testFunc(10,mean) mpg cyl disp hp drat wt qsec vs am gear carb [1,] 20.37 5.8 208.61 122.8 3.538 3.1280 18.581 0.6 0.3 3.6 2.5 [2,] 19.89 6.6 259.25 149.6 3.552 3.6689 18.301 0.4 0.3 3.4 2.9 [3,] 20.39 6.2 228.25 152.6 3.654 2.8633 16.914 0.3 0.5 3.9 2.6 > class(testFunc(10,mean)) [1] "matrix"
I also tried debugging testFunc
and calling it from apply
and it seems that the arguments passed correctly:
> debug(testFunc) > apply(dframe, 1, function(x) testFunc(x[1], x[2])) debugging in: testFunc(x[1], x[2]) debug: rollapply(mtcars, width = a, by = a, FUN = b, align = "left") Browse[2]> print(a) $Var1 [1] 1 Browse[2]> print(b) $Var2 function (x, na.rm = FALSE) UseMethod("median") <bytecode: 0x08244ffc> <environment: namespace:stats> Browse[2]> n Error in get(as.character(FUN), mode = "function", envir = envir) : object 'b' of mode 'function' was not found
Questions:
- What is a mistake and what am I doing wrong?
- How to replace a nested loop with
expand.grid
and call an internal function with several arguments? - How to return a list of matrices using
*apply
function families?
PS: I think it would be easy to achieve using two nested loops, but I wonder if there is an R-way.
PPS: Here is the answer to a similar error ( object 'b' of mode 'function' was not found
) with the conclusion that b
(in my case) conflicts with named arguments with another function, But I do not see this problem in my code.