7

Trying to apply a matrix to a function, using mapply without success

I'm trying to solve a set of equations for different parameters. In a more simplistic form of the set of functions, I'm trying to pass a function to a matrix - constants -

 a b c [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 

and trying to solve the the equation 3*a + 2*b + 3*c and return the answer for each row in the matrix. I have changed the original function to a linear and more simple one - that is why I prefer using #mapply and that former explanations have not assisted me.

building the matrix

my_vector <- 1:9 constants <- matrix(my_vector, 3, 3) colnames(constants) <- c("a", "b", "c") constants 

the target function

fun_abc <- function(a, b, c){ return(3 * a + 2 * b + 3 * c) } 

applying constants to the function

mapply(fun_abc, 2, constants) 

I keep getting Error in (function (a, b, c) : argument "c" is missing, with no default Can anyone spot the problems?

2
  • The function I've used is a simplified version of the function that I actually apply. It is not a linear function, therefore - I prefered using mapply. I edited the question as well. I commented on the post and edited the original question Commented Sep 16, 2019 at 10:36
  • Please clarify and/or reply to comments before posting a new question. Commented Sep 16, 2019 at 13:51

3 Answers 3

4

You can directly multiply values and take rowSums to get row-wise sum

vals <- c(3, 2, 3) rowSums(t(t(constants) * vals)) #[1] 32 40 48 

We use transpose since constants * vals would multiply vals in each column, so the first transpose is to multiply vals row-wise and the second transpose is to get matrix in original format again. If we would always have a square matrix (nrow == ncol), we can reduce one transpose and use colSums instead to get the same value.

colSums(t(constants) * vals) #[1] 32 40 48 

If we want to avoid transposing we can also use sweep

rowSums(sweep(constants, 2, vals, `*`)) 
Sign up to request clarification or add additional context in comments.

Comments

2

One simple way to do this using matrix multiplication, and then changing it to vector if you want so:

my_vector <- 1:9 constants <- matrix(my_vector, 3, 3) colnames(constants) <- c("a", "b", "c") vals <- c(3, 2, 3) c(constants %*% vals) #> [1] 32 40 48 

Or, redefine your function and use apply:

fun_x <- function(x){ sum(x * vals) # same as 3 * x[1] + 2 * x[2] + 3 * x[3] } apply(constants, 1, fun_x) 

Comments

1

An alternative albeit admittedly overly complicated possibility:

 fun_abc <- function(my_matrix,multiplier,...){ columns <- match(c(...),colnames(my_matrix)) rowSums(mapply(function(x, y) my_matrix[,x] * y , columns, multiplier)) } fun_abc(constants, c(3,2, 3),"a", "b", "c") [1] 32 40 48 

This assumes that the user would like to programmatically access columns, otherwise:

constants[,"a"] * 3 + constants[,"b"] * 2 + constants[,"c"] * 3 [1] 32 40 48 

2 Comments

The function I've used is a simplified version of the function that I actually apply. It is not a linear function, therefore - I prefered using mapply. I edited the question as well.
I cannot see a difference between your question and the original question. Could you actually include what the "non-linear" function should change to?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.