Reputation: 2652
My problem is basically this:
I have a list, L, where each element is a matrix of the same dimension. I need to multiply each matrix inside this list by its corresponding element in an outside vector h, and then sum all the matrices.
set.seed(101)
L <- replicate(3, matrix(rnorm(4), 2), simplify = FALSE)
h <- 2:4
# I need this
L[[1]] * h[1] + L[[2]] * h[2] + L[[3]] * h[3]
Given that I need to experiment with a different number of matrices, and I have a bunch of them, I've got to do it in a smart way. My idea was
L1 <- lapply(L, function(x) x * h[x])
L2 <- Reduce('+', L1)
Where "h[x]" would be indexing the vector h by the index of the matrix x inside the list L, so I would get
L1 = list(L[[1]] * h[1], L[[2]] * h[2], L[[3]] * h[3])
So, the question is, how to I get the index of an element in a list by using the element itself? Something like h[L[[m1]]] to get h[1].
Or, if you got any other way of solving my problem, how do I do it?
Upvotes: 5
Views: 232
Reputation: 38500
Using the foreach
package, we can get the result as follows:
library(foreach)
foreach(i=seq_along(h), .combine="+") %do% {
L[[i]] * h[i]
}
The %do%
loop runs through performing the element-wise multiplication, then the output summed using the .combine
argument. This outputs the same result as Ben's Map
-Reduce
method.
Upvotes: 2
Reputation: 66819
I might do
Reduce(
function(z,i) z + L[[i]]*h[i],
seq_along(L),
init = array(0, dim(L[[1]]))
)
Testing it on Ben's example data, I see the same result so I guess it works.
This is similar to an answer @eddi posted on my question about linear combos.
Upvotes: 4
Reputation: 226182
I think you're looking for mapply()
/Map()
(Map
is slightly easier here because it doesn't try to simplify the results):
?Map
:
‘Map’ applies a function to the corresponding elements of given vectors ... ‘Map’ is a simple wrapper to ‘mapply’ which does not attempt to simplify the result ...
?mapply
:
‘mapply’ applies ‘FUN’ to the first elements of each ... argument, the second elements, the third elements, and so on
Set up example:
set.seed(101)
L <- replicate(3,matrix(rnorm(4),2),simplify=FALSE)
h <- 2:4
Do it:
Reduce("+",Map("*",L,h))
Upvotes: 6