Reputation: 83537
I have a function
function (x, y) { ... }
which expects two vectors x
and y
and returns a value calculated from them.
I want to apply this function pairwise to the column vectors of two matrices xs
and ys
. From R, iterating over the row vectors of a matrix I found mapply()
but this seems to apply the function pairwise to each element of the matrix. Instead, I want to apply the function to an entire column. How do I do this?
For clarification, here's a contrived example:
xs <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 3, ncol = 2)
ys <- matrix(c(25, 26, 27, 28, 29, 30), nrow = 3, ncol = 2)
dot <- function(x, y) sum(x*y)
Upvotes: 6
Views: 4315
Reputation: 9656
Nobody yet mentioned asplit
(added in R 3.6.0) - the function made specifically for this case.
Example:
mapply(dot, asplit(xs, 2), asplit(ys, 2))
Same but using rows:
mapply(dot, asplit(xs, 1), asplit(ys, 1))
Upvotes: 5
Reputation: 4233
You can also use mapply
like this:
mapply(function(i, x = xs, y = ys) dot(x[,i],y[,i]), 1:ncol(xs))
or use purrr
:
purrr::map_dbl(1:ncol(xs), function(i,x,y) dot(x[,i],y[,i]), x = xs, y = ys)
Upvotes: 1
Reputation: 887213
Using a simple for
loop
v1 <- numeric(ncol(xs))
for(i in seq_along(v1)) v1[i] <- dot(xs[,i], ys[,i])
v1
#[1] 158 437
Or with vectorized option
colSums(xs * ys)
#[1] 158 437
Upvotes: 2
Reputation: 5673
mapply expect list or data frame to work on column:
mapply(dot,as.data.frame(xs),as.data.frame(ys))
V1 V2
158 437
Upvotes: 1
Reputation: 51998
Here is one way:
xs <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 3, ncol = 2)
ys <- matrix(c(25, 26, 27, 28, 29, 30), nrow = 3, ncol = 2)
dot <- function(x, y) {
sum(x*y)
}
dots <- sapply(1:ncol(xs),function(i) dot(xs[,i],ys[,i])) #dots = c(158, 437)
Upvotes: 2