Fastest way to multiply matrix columns with vector elements in R
Use some linear algebra and perform matrix multiplication, which is quite fast in R
.
eg
m %*% diag(v)
some benchmarking
m = matrix(rnorm(1200000), ncol=6)
v=c(1.5, 3.5, 4.5, 5.5, 6.5, 7.5)
library(microbenchmark)
microbenchmark(m %*% diag(v), t(t(m) * v))
## Unit: milliseconds
## expr min lq median uq max neval
## m %*% diag(v) 16.57174 16.78104 16.86427 23.13121 109.9006 100
## t(t(m) * v) 26.21470 26.59049 32.40829 35.38097 122.9351 100
Fastest way for multiplying a matrix to a vector
sweep
seems to run a bit faster on my machine
sweep(mat, 2, v, FUN = "*")
Some benchmarks:
> microbenchmark(mat %*% diag(v),sweep(mat, 2, v, FUN = "*"))
Unit: milliseconds
expr min lq median uq max neval
%*% 214.66700 226.95551 231.2366 255.78493 349.1911 100
sweep 42.42987 44.72254 62.9990 70.87403 127.2869 100
Fastest way to hadamard multiply all matrix columns with another matrix
You can try apply(A, 2, '*', B)
and to come the the same like colmat_prod
use array(apply(A, 2, '*', B), c(dim(B), ncol(A)))
:
identical(array(apply(A, 2, '*', B), c(dim(B), ncol(A))), colmat_prod(A, B))
#[1] TRUE
Another option is to use rep
for the columns of A
:
array(A[,rep(seq_len(ncol(A)), each=ncol(B))] * as.vector(B), c(dim(B), ncol(A)))
Timings:
library(microbenchmark)
microbenchmark(colmat_prod(A1, B1),
colmat_prod_vec(A1, B1),
array(apply(A1, 2, '*', B1), c(dim(B1), ncol(A1))),
array(A1[,rep(seq_len(ncol(A1)), each=ncol(B1))] * as.vector(B1), c(dim(B1), ncol(A1))),
times = 10)
#Unit: milliseconds
# expr min lq mean median uq max neval cld
# colmat_prod(A1, B1) 831.5437 857.0305 910.5694 878.6842 999.5354 1025.0915 10 c
# colmat_prod_vec(A1, B1) 981.9241 1010.9482 1174.1700 1162.7004 1319.3478 1444.6158 10 d
# array(apply(A1, 2, "*", B1), c(dim(B1), ncol(A1))) 716.1469 725.7862 765.4987 732.2520 789.3843 907.4417 10 b
# array(A1[, rep(seq_len(ncol(A1)), each = ncol(B1))] * as.vector(B1), c(dim(B1), ncol(A1))) 404.8460 406.2848 430.4043 428.2685 458.9400 462.0634 10 a
Multiplying columns in a matrix by a scalar in R
Another base R option using %*%
and diag
> mat %*% diag(scalar)
[,1] [,2] [,3]
[1,] 1 8 21
[2,] 2 10 24
[3,] 3 12 27
multiply each columns of a matrix by a vector
vect*mat
[,1] [,2] [,3] [,4]
[1,] 2 8 14 20
[2,] 4 10 16 22
[3,] 6 12 18 24
The vector vect
is recycled by column. Better to experiment with different values to see the process.
Multiply elements of a matrix with vector values
First you need to coerce coords
to a matrix for indexing, then reverse the column order. Then it's just a simple lapply()
loop.
coords <- as.matrix(coords)[, 2:1]
lapply(multis, function(x) {
M[coords] <- M[coords] * x
M
})
resulting in
[[1]]
[,1] [,2] [,3] [,4] [,5]
[1,] 0.1 5 9 13.0 17.0
[2,] 2.0 6 10 1.4 18.0
[3,] 3.0 7 11 15.0 1.9
[4,] 4.0 8 12 16.0 20.0
[[2]]
[,1] [,2] [,3] [,4] [,5]
[1,] 2 5 9 13 17
[2,] 2 6 10 28 18
[3,] 3 7 11 15 38
[4,] 4 8 12 16 20
[[3]]
[,1] [,2] [,3] [,4] [,5]
[1,] 100 5 9 13 17
[2,] 2 6 10 1400 18
[3,] 3 7 11 15 1900
[4,] 4 8 12 16 20
Multiply columns in a data frame by a vector
Transposing the dataframe works.
c1 <- c(1,2,3)
c2 <- c(4,5,6)
c3 <- c(7,8,9)
d1 <- data.frame(c1,c2,c3)
v1 <- c(1,2,3)
t(t(d1)*v1)
# c1 c2 c3
#[1,] 1 8 21
#[2,] 2 10 24
#[3,] 3 12 27
EDIT: If all columns are not numeric, you can do the following
c1 <- c(1,2,3)
c2 <- c(4,5,6)
c3 <- c(7,8,9)
d1 <- data.frame(c1,c2,c3)
# Adding a column of characters for demonstration
d1$c4 <- c("rr", "t", "s")
v1 <- c(1,2,3)
#Choosing only numeric columns
index <- which(sapply(d1, is.numeric) == TRUE)
d1_mat <- as.matrix(d1[,index])
d1[,index] <- t(t(d1_mat)*v1)
d1
# c1 c2 c3 c4
#1 1 8 21 rr
#2 2 10 24 t
#3 3 12 27 s
Multiply rows of matrix by vector?
I think you're looking for sweep()
.
# Create example data and vector
mat <- matrix(rep(1:3,each=5),nrow=3,ncol=5,byrow=TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
vec <- 1:5
# Use sweep to apply the vector with the multiply (`*`) function
# across columns (See ?apply for an explanation of MARGIN)
sweep(mat, MARGIN=2, vec, `*`)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 2 4 6 8 10
[3,] 3 6 9 12 15
It's been one of R's core functions, though improvements have been made on it over the years.
Related Topics
Automatic Documentation of Datasets
Determining the Distance Between Two Zip Codes (Alternatives to Mapdist)
Plotting Multiple Curves Same Graph and Same Scale
Connecting Points with Lines in Ggplot2 in R
Sum of Antidiagonal of a Matrix
How to Use a MACro Variable in R? (Similar to %Let in Sas)
How to Show the Progress of Code in Parallel Computation in R
How to Name the List of the Group_Split Output in Dplyr
R Dplyr Join by Range or Virtual Column
Fast Replacing Values in Dataframe in R
Add Density Lines to Histogram and Cumulative Histogram
Calling a Function from a Namespace
Sendmailr (Part2): Sending Files as Mail Attachments
Reading Excel File: How to Find the Start Cell in Messy Spreadsheets