Creating a new matrix in R using old matrix values as exponents - r

If I have a matrix mat1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
it is possible via a very simple command to square all individual values by
mat1 * mat1
[,1] [,2] [,3]
[1,] 1 9 25
[2,] 4 16 36
Now, what I want to do is to create a new matrix where all values are computed by e^(old_value), e.g., e^1, e^2, e^3 and so forth. How can I do this?

exp computes the exponential function
> mat1 <- matrix(1:6, nrow=2)
> exp(mat1)
[,1] [,2] [,3]
[1,] 2.718282 20.08554 148.4132
[2,] 7.389056 54.59815 403.4288

Related

How can I multiply two large matrices by corresponding columns and rows

I have two matrices for example:
> A
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> B
[,1] [,2]
[1,] 7 10
[2,] 8 11
[3,] 9 12
and I want a vector called C whose element C[i]=A[i,]*B[,i], so the outcome should be:
> C
[,1]
[1,] 76
[2,] 136
I used the for loop for (i in 1:2) {C[i]=A[i,]%*%B[,i]}. But it is very slow.
And I also tried A%*%B and take elements in the diagonal, and it just make my computer crash when the matrix is large.
Could you please give me some suggestions? Thanks so much!
A straight multiplication (not matrix multiplication but element-wise multiplication) could work for what we want. That gets the multiplications we want - after that we just want to take the sum of the rows. If we need the result to be a column matrix we can convert to matrix.
> A <- matrix(1:6, nrow = 2)
> A
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> B <- matrix(7:12, ncol = 2)
> B
[,1] [,2]
[1,] 7 10
[2,] 8 11
[3,] 9 12
> rowSums(A * t(B))
[1] 76 136
> as.matrix(rowSums(A * t(B)))
[,1]
[1,] 76
[2,] 136
mapply(function(a,b) sum(a*b), asplit(A, 1), asplit(B, 2))
# [1] 76 136

Divide each element in a matrix by one element in R

Consider the following matrix:
matrix <- matrix(1:9, nrow = 3, ncol = 3)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
For the two first columns ([,1] and [,2]), I want to divide each element until row [3,] with the number in row [3,]. That is, I want to get the following matrix:
[,1] [,2]
[1,] 1/3 4/6
[2,] 2/3 5/6
How do I do that in R?

R, Select a Subset of Matrix

Suppose I have 2 matrices m and m.ind. The first one contains actual data while the smaller one contains row indices.
m
[,1] [,2] [,3] [,4]
[1,] 0.23094453 -0.1379296 0.4173233 -1.7767756
[2,] -1.15772946 -0.1111935 1.0654023 0.6228674
[3,] 0.24707599 -0.6900143 0.9702020 -0.5222834
[4,] -0.09111356 -0.2217942 -0.1016292 1.3222310
[5,] 1.75737562 0.1829077 1.4032035 -0.3634403
m.ind
[,1] [,2] [,3] [,4]
[1,] 2 1 3 5
[2,] 2 2 4 4
I would like to create a subset of the matrix m whose row ids are the elements of the matrix m.ind.
m.sub
[,1] [,2] [,3] [,4]
[1,] -1.157729 -0.1379296 0.9702020 -0.3634403
[2,] -1.157729 -0.1111935 -0.1016292 1.3222310
I tried the function below:
test=apply(m, 2, function(x) x[m.ind])
Your assistance is appreciated.
You could produce the indices for subsetting m by either
m.ind2 <- m.ind + nrow(m)*(col(m.ind)-1)
or
m.ind2 <- cbind(as.vector(m.ind),as.vector(col(m.ind)))
And then do:
matrix(m[m.ind2],nrow=nrow(m.ind))
This solution employs the fact that matrix in R is essentially a vector with dim attributes.
Here is a sample data set:
set.seed(1)
m <- matrix(runif(20),ncol=4)
m.ind <- matrix(c(2,2,1,2,3,4,5,4),nrow=2)
and output:
[,1] [,2] [,3] [,4]
[1,] 0.3721239 0.8983897 0.6870228 0.7774452
[2,] 0.3721239 0.9446753 0.3841037 0.3800352

Calculate inverse of a non-square matrix in R

I'm pretty new to the R language and trying to find out how you can calculate the inverse of a matrix that isn't square. (non-square? irregular? I'm unsure of the correct terminology).
From my book and a quick google search, (see source), I've found you can use solve(a) to find the inverse of a matrix if a is square.
The matrix I have created is, and from what I understand, not square:
> matX<-matrix(c(rep(1, 8),2,3,4,0,6,4,3,7,-2,-4,3,5,7,8,9,11), nrow=8, ncol=3);
> matX
[,1] [,2] [,3]
[1,] 1 2 -2
[2,] 1 3 -4
[3,] 1 4 3
[4,] 1 0 5
[5,] 1 6 7
[6,] 1 4 8
[7,] 1 3 9
[8,] 1 7 11
>
Is there a function for solving a matrix of this size or will I have to do something to each element? as the solve() function gives this error:
Error in solve.default(matX) : 'a' (8 x 3) must be square
The calculation I'm trying to achieve from the above matrix is: (matX'matX)^-1
Thanks in advance.
ginv ginv in the MASS package will give the generalized inverse of a matrix. Premultiplying the original matrix by it will give the identity:
library(MASS)
inv <- ginv(matX)
# test it out
inv %*% matX
## [,1] [,2] [,3]
## [1,] 1.000000e+00 6.661338e-16 4.440892e-15
## [2,] -8.326673e-17 1.000000e+00 -1.110223e-15
## [3,] 6.938894e-17 8.326673e-17 1.000000e+00
As suggested in the comments this can be displayed in a nicer way using zapsmall:
zapsmall(inv %*% matX)
## [,1] [,2] [,3]
## [1,] 1 0 0
## [2,] 0 1 0
## [3,] 0 0 1
The inverse of matX'matX is now:
tcrossprod(inv)
## [,1] [,2] [,3]
## [1,] 0.513763935 -0.104219636 -0.002371406
## [2,] -0.104219636 0.038700372 -0.007798748
## [3,] -0.002371406 -0.007798748 0.006625269
solve however, if you aim is to calculate the inverse of matX'matX you don't need it in the first place. This does not involve MASS:
solve(crossprod(matX))
## [,1] [,2] [,3]
## [1,] 0.513763935 -0.104219636 -0.002371406
## [2,] -0.104219636 0.038700372 -0.007798748
## [3,] -0.002371406 -0.007798748 0.006625269
svd The svd could also be used and similarly does not require MASS:
with(svd(matX), v %*% diag(1/d^2) %*% t(v))
## [,1] [,2] [,3]
## [1,] 0.513763935 -0.104219636 -0.002371406
## [2,] -0.104219636 0.038700372 -0.007798748
## [3,] -0.002371406 -0.007798748 0.006625269
ADDED some additional info.
You can do what's called a "Moore–Penrose pseudoinverse". Here's a function exp.matthat will do this for you. There is also an example outlining it's use here.
exp.mat():
#The exp.mat function performs can calculate the pseudoinverse of a matrix (EXP=-1)
#and other exponents of matrices, such as square roots (EXP=0.5) or square root of
#its inverse (EXP=-0.5).
#The function arguments are a matrix (MAT), an exponent (EXP), and a tolerance
#level for non-zero singular values.
exp.mat<-function(MAT, EXP, tol=NULL){
MAT <- as.matrix(MAT)
matdim <- dim(MAT)
if(is.null(tol)){
tol=min(1e-7, .Machine$double.eps*max(matdim)*max(MAT))
}
if(matdim[1]>=matdim[2]){
svd1 <- svd(MAT)
keep <- which(svd1$d > tol)
res <- t(svd1$u[,keep]%*%diag(svd1$d[keep]^EXP, nrow=length(keep))%*%t(svd1$v[,keep]))
}
if(matdim[1]<matdim[2]){
svd1 <- svd(t(MAT))
keep <- which(svd1$d > tol)
res <- svd1$u[,keep]%*%diag(svd1$d[keep]^EXP, nrow=length(keep))%*%t(svd1$v[,keep])
}
return(res)
}
example of use:
source("exp.mat.R")
X <- matrix(c(rep(1, 8),2,3,4,0,6,4,3,7,-2,-4,3,5,7,8,9,11), nrow=8, ncol=3)
iX <- exp.mat(X, -1)
zapsmall(iX %*% X) # results in identity matrix
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1

Mean on the third dimension in R

Is there any quick way or build-in function in R to calculation the mean values based on the third dimension?
For example my array is:
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 11 13
[2,] 12 14
, , 3
[,1] [,2]
[1,] 21 23
[2,] 22 24
My output would be:
[,1] [,2]
[1,] mean(1,11,21) mean(3,13,23)
[2,] mean(2,12,22) mean(4,14,24)
Thanks!
?apply is your friend for these types of tasks.
# Make the sample data
j <- array(c(1:4, 11:14, 21:24), c(2,2,3))
# For each combination in the 1st and 2nd dimension
# average over the values in the 3rd.
apply(j, c(1,2), mean)

Resources