This question already has answers here:
Multiply rows of matrix by vector?
(6 answers)
Closed 1 year ago.
Suppose I have the following:
mat <- matrix(1:9, ncol = 3)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
Now I would like to multiply each column of the matrix by a scalar
scalar = c(1,2,3)
I would like the first element of scalar to multiply the first column, the second element multiply the second column and the third scalar the third column.
To obtain the following output
[,1] [,2] [,3]
[1,] 1 8 21
[2,] 2 10 24
[3,] 3 12 27
Could anyone help me with this?
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
We replicate the 'scalar' and multiply
mat * scalar[col(mat)]
Or with sweep
sweep(mat, 2, scalar, `*`)
[,1] [,2] [,3]
[1,] 1 8 21
[2,] 2 10 24
[3,] 3 12 27
Related
I have two matrices that i want to sum
mat1<-matrix(1:4,2,2)
mat2<-matrix(5:8,2,2)
mat1
[,1] [,2]
[1,] 1 3
[2,] 2 4
mat2
[,1] [,2]
[1,] 5 7
[2,] 6 8
what i want is this
mat_sum
[,1] [,2]
[1,] 6 10
[2,] 8 12
I tried
mat_sum <- sapply(seq_along(mat1), function(i)
mat1[[i]]+mat2[[i]])
but then it doesnt return a matrix
[1] 6 8 10 12
How can i get it to return a matrix?
We can do a regular + which will preserve the matrix format and does the elementwise summation
mat1 + mat2
# [,1] [,2]
#[1,] 6 10
#[2,] 8 12
If there are many matrices, place it in a list and use Reduce with +
Reduce(`+`, mget(paste0("mat", 1:2)))
I'm having a question about indexing 3 dim arrays.
Say I have a 3 dimensional array
x<- c(1:36)
dim(x) <- c(3,4,3)
Now I want to extract values out of this array according to a matrix holding the 3rd dimension indices for all [i,j] positions.
y <- c(rep(1,4),rep(2,4),rep(3,4))
dim(y) <- c(3,4)
y
[,1] [,2] [,3] [,4]
[1,] 1 1 2 3
[2,] 1 2 2 3
[3,] 1 2 3 3
So the result should be giving this:
[,1] [,2] [,3] [,4]
[1,] 1 4 19 34
[2,] 2 17 20 35
[3,] 3 18 33 36
Is there some elegant way to do this? I know how to use two for loops to go over the array, but this is too slow for my data.
help("[") tells us this:
Matrices and arrays
[...]
A third form of indexing is via a numeric matrix with the one column for each dimension: each row of the
index matrix then selects a single element of the array, and the
result is a vector.
Thus, we transform your y matrix to a shape that conforms with this.
library(reshape2)
z <- x[as.matrix(melt(y))]
dim(z) <- dim(y)
# [,1] [,2] [,3] [,4]
#[1,] 1 4 19 34
#[2,] 2 17 20 35
#[3,] 3 18 33 36
I'm looking at this as an opportunity for some code golf. It's definitely possible to do this as a one-liner:
> `dim<-`(x[cbind(c(row(y)), c(col(y)), c(y))], dim(y))
[,1] [,2] [,3] [,4]
[1,] 1 4 19 34
[2,] 2 17 20 35
[3,] 3 18 33 36
As #Roland's answer shows, matrix/array indexing involves creating an n-column matrix and setting the columns equal to row, column, etc. position of each dimension of an n-dimensional array. We can use the row() and col() functions to extract the row and column positions of each element in y:
> row(y)
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 2 2 2 2
[3,] 3 3 3 3
> col(y)
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 1 2 3 4
[3,] 1 2 3 4
and y itself gives the third-dimension positions. wrapping each of those in c() turns them into a vector, so that they can be cbind-ed together to create an extraction matrix.
Then, there's just some fun use of dim<-() to fit it all on one line.
If I had a matrix like:
[,1] [,2]
[1,] 1 7
[2,] 2 8
[3,] 3 9
[4,] 4 10
[5,] 5 11
[6,] 6 12
Does anyone have an idea as to how I might create a new matrix from the above that looks like:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 7 3 9 5 11
[2,] 2 8 4 10 6 12
We create a grouping variable with ?gl and use the arguments n=nrow(m1), k=2 and length=nrow(m1). We split the matrix ('m1'), unlist, and create a new matrix with nrow=2.
matrix(unlist(split(m1,as.numeric(gl(nrow(m1), 2, nrow(m1))))),nrow=2)
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 7 3 9 5 11
#[2,] 2 8 4 10 6 12
Or another option is converting to array by specifying the dimensions. Here I used c(2, 2, 3) as we can get a 2x2 matrix for the first two dimensions and the third is based on the nrow(m1)/2. Then, we can permute the dimensions of the array using aperm, concatenate (c) to form a vector and convert to matrix.
matrix(c(aperm(array(t(m1), c(2, 2,3)),c(2,1,3))), nrow=2)
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 7 3 9 5 11
#[2,] 2 8 4 10 6 12
data
m1 <- structure(1:12, .Dim = c(6L, 2L))
Here' another option: First the matrix is transformed into one with two rows, then the odd and even numbered columns are rearranged:
m3 <- m2 <- matrix(c(m),nrow = 2) #take data from original matrix, convert it into a matrix with two rows and store a copy in m2 and m3
m3[,seq(1,ncol(m2),2)] <- m2[,1:(ncol(m2)/2)] #define the odd-numbered columns of m3
m3[,seq(2,ncol(m2),2)] <- m2[,(ncol(m2)/2+1):ncol(m2)] # same for the even-numbered columns
> m3
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 7 3 9 5 11
#[2,] 2 8 4 10 6 12
First create a "row" vector and a "column" vector in R:
> row.vector <- seq(from = 1, length = 4, by = 1)
> col.vector <- {t(seq(from = 1, length = 3, by = 2))}
From that I'd like to create a matrix by, e.g., multiplying each value in the row vector with each value in the column vector, thus creating from just those two vectors:
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 6 10
[3,] 3 9 15
[4,] 4 12 20
Can this be done with somehow using apply()? sweep()? ...a for loop?
Thank you for any help!
Simple matrix multiplication will work just fine
row.vector %*% col.vector
# [,1] [,2] [,3]
# [1,] 1 3 5
# [2,] 2 6 10
# [3,] 3 9 15
# [4,] 4 12 20
You'd be better off working with two actual vectors, instead of a vector and a matrix:
outer(row.vector,as.vector(col.vector))
# [,1] [,2] [,3]
#[1,] 1 3 5
#[2,] 2 6 10
#[3,] 3 9 15
#[4,] 4 12 20
Here's a way to get there with apply. Is there a reason why you're not using matrix?
> apply(col.vector, 2, function(x) row.vector * x)
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 6 10
## [3,] 3 9 15
## [4,] 4 12 20
Let M be the matrix:
[,1] [,2]
[1,] 1 9
[2,] 3 12
[3,] 6 4
[4,] 7 2
I would like to extract all rows with entries equal to the components of the vector
v <- c(3,6,1) from column [,1] in M producing the submatrix m:
[,1] [,2]
[1,] 1 9
[2,] 3 12
[3,] 6 4
I tried
m <- M[which(M[,1] == v), ]
Obtaining the error message longer object length is not a multiple of shorter object length.
Using the transpose t(v) of v does not help.
using %in%:
M[M[,1] %in% v,]
[,1] [,2]
[1,] 1 9
[2,] 3 12
[3,] 6 4