'Is there a way to create a matrix that would contain functions as input values in R?

For example, the MATLAB code for something I need to write looks like this

 f = @(x) [ 100*x(1) - 4*x(1)*x(2);

     -20*x(2) + 0.01*x(1)*x(2)];

 J = @(x) [100-4*x(2), -4*x(1);

      0.01*x(2), -20+0.01*x(1)];

What would be an analog in R to store functions as matrix values? In R, I tried

 rabbits <- function(x) { #defined a function

100*x(1) - 4*x(1)*x(2) }


 foxes <- function(x) { #defined a second function

 -20*x(2) + 0.01*x(1)*x(2)}

function_vector <- matrix(0, 2, 1) # created a 0 matrix to later append values

function_vector[1,1] <- function_vector[1,1] + rabbits #added values to 0 matrix

function_vector[2,1] <- function_vector[2,1] + foxes

Apparently, I can't store functions in matrixes, as it gives me an error "non-numeric argument to binary operator". Generally, I need this matrix for manual two-dimensional root finding, so if you know any other way to code it (apart from inbuilt functions), then I would also appreciate that :)



Solution 1:[1]

You can store functions in a list array. It is created by setting the dim attribute of a list.

# works without names, only added them to illustrate the order they will appear in the array in. 
l <- list(
  f11 = \(x) x,
  f21 = \(x) x^2,
  f12 = \(x) 2*x,
  f22 = \(x) 2*x^2
)

dim(l) <- c(2, 2)  

l[1,2]
#> [[1]]
#> \(x) 2*x

Alternatively, you can also store functions in list variables of data frames. I am using a tibble here, because the constructor data.frame() doesn't like lists of functions for some reason. But it is possible to coerce it to a plain data frame if you prefer.

d <- tibble::tibble(
  f1 = list(\(x) x,
            \(x) 2*x),
  f2 = list(\(x) x^2,
            \(x) 2*x^2)
)

d
#> # A tibble: 2 × 2
#>   f1     f2    
#>   <list> <list>
#> 1 <fn>   <fn>  
#> 2 <fn>   <fn>

as.data.frame(d)
#>                     f1                     f2
#> 1     function (x) , x     function (x) , x^2
#> 2 function (x) , 2 * x function (x) , 2 * x^2

Note that I have used the shorthand function syntax \(...) ... here. If you have an R version older than 4.1 you will have to replace it with function(...) {...}.

Created on 2022-04-01 by the reprex package (v2.0.1)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1