Calculating exp() of each element in matrix using R - r

how can I take exp() of each element in a matrix? I have mymatrix = matrix(c(2, 4, 3, 1, 5, 7), 3,2) and tried using res<-expm(mymatrix) but it requires mymatrix to be square. Is there another way to calculate each element so
res is matrix(c(exp(2), exp(4), exp(3), exp(1), exp(5), exp(7), 3,2) ?

res <- mymatrix
res [] <- exp(res)
> res
[,1] [,2]
[1,] 7.389056 2.718282
[2,] 54.598150 148.413159
[3,] 20.085537 1096.633158
Here you go.

Related

R nested for loops

I am trying to do a nested for loop in R and am a bit confused on how to make it work. I want to assign rows 1:4 of matrix m based upon a function of i. Below I have generalization of my current code. I believe I need to double loop as my actual code for i depends on the values 5, 10, 15, 25.
f <- function()
m <- matrix(nrow = 4)
for (i in c(5, 10, 15, 25)) {
for (j in c(1:4)) {
m[j,1] <- f(i)
}
}
which results in:
> m
[,1]
[1,] f(25)
[2,] f(25)
[3,] f(25)
[4,] f(25)
My desired output is below and I'm not sure how to do the loop to produce these results.
> m
[,1]
[1,] f(5)
[2,] f(10)
[3,] f(15)
[4,] f(25)
I think doing a nested for-loop would be hard so I ended up doing:
f <- function()
sapply(c(5, 10, 15, 25), f) %>%
matrix()

Conditional function in R which returns a matrix

I am sorry in advance if that's a silly question, but I am a bit new to it.
I would like to write a for loop where the input is a time sequence. Based on the time conditions I would like to select either mat1, mat2, or mat3 to substitute the "mat" parameter and multiply it by 2.
output <- mat*2 #general function
For each time point, I need to have an output.
time=seq(0,10, by=1)
mat1 <- matrix(data = rexp(9, rate = 10), nrow = 3, ncol = 3)
mat2 <- matrix(data = rexp(9, rate = 10), nrow = 3, ncol = 3)
mat3 <- matrix(data = rexp(9, rate = 10), nrow = 3, ncol = 3)
I would like when the time <= 3 the "mat1" to be selected
when the time>3 & time<=6 the "mat2" to be selected
and when the time >6 the "mat3" to be selected and then multiplied by 2.
I know that all this is a bit sketchy but any help would be highly appreciated.
By the way, if you want a list of consecutive integers you can simply use time <- 0:10
Here is one method
lapply(as.character(cut(time,c(-1,3.1,6.1,10),labels=c('mat1','mat2','mat3'))), function(x) get(x)*2)
[[1]]
[,1] [,2] [,3]
[1,] 0.4013379 1.2690301 0.142831401
[2,] 0.1536697 0.1132762 0.040964909
[3,] 0.1412248 0.2209273 0.007446217
[[2]]
[,1] [,2] [,3]
[1,] 0.4013379 1.2690301 0.142831401
[2,] 0.1536697 0.1132762 0.040964909
[3,] 0.1412248 0.2209273 0.007446217
...
[[10]]
[,1] [,2] [,3]
[1,] 0.16712782 0.06451693 0.06554605
[2,] 0.03614116 0.18526124 0.46443236
[3,] 0.53055007 0.01203971 0.16585931
[[11]]
[,1] [,2] [,3]
[1,] 0.16712782 0.06451693 0.06554605
[2,] 0.03614116 0.18526124 0.46443236
[3,] 0.53055007 0.01203971 0.16585931

R: put results of function in corresponding original position of inputs after a subset

Suppose I have two matrices mat and obj:
time <- c(1, 1, 2, 2, 3, 3)
money <- c(2, 2, 4, 4, 6, 6)
ownership <- c(1, 0, 1, 0, 1, 0)
randomstuff <- matrix(runif(18),nrow = 3)
mat <- rbind(time, money, ownership, randomstuff)
dat <- c(1, 0, 2, 0, 3, 0)
obj <- matrix(dat,nrow=1)
I am running them through a function:
f <- function(mat,obj){fake function outputting a vector the same length as obj}
soln <- f(mat, obj).
where soln is a 1x6 matrix.
How could I transform (elegantly - this is actually a 70000+ column matrix) the matrices mat and obj to:
time <- c(1, 2, 3)
money <- c(2, 4, 6)
ownership <- c(1, 1, 1)
mat <- rbind(time, money, ownership, randomstuff)
dat <- list(1, 2, 3)
obj <- matrix(dat,nrow=1)
with the soln being a 1x3 matrix.
soln= [,1] [,2] [,3]
[1,] 4.151969 5.759826 5.537563
where the decision to exclude a column from mat is based on the value in ownership[]=0 and the same for obj. The added difficulty, is that I need to be able to assign the output in soln to the mapped to the corresponding original position in a larger SOLN matrix. In this case columns 1,3,5. Ownership is randomly assigned, so there will be no pattern other than the zeros described above.
The suggestion to use:
obj2 <- obj[, as.logical(ownership), drop = FALSE]
mat2 <- mat[, as.logical(ownership)]
works perfectly for that piece. How do I put the soln values in positions 1,3,5 of a larger SOLN matrix? The SOLN matrix below is an example of possible output. In this case, I want columns 1, 3, and 5 to be filled by this function. Subsequent operations (same operation different ownership) will fill columns 2, 4 and 6.
SOLN = [,1] [,2] [,3] [,4] [,5] [,6]
[1,] 4.151969 1.08251 5.759826 3.368613 5.537563 3.471643
Any ideas?
I have a partial answer. I can find the column index:
soln2 <- c(7,8,9)
index <- which(ownership==1, arr.ind=TRUE)
> index
[1] 1 3 5
Now, I know that I need to create a result space:
SOLN <- matrix(data=NA,nrow=1,ncol=6)
> SOLN
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] NA NA NA NA NA NA
> SOLN[,1]<-soln2[1]
> SOLN[,3]<-soln2[2]
> SOLN[,5]<-soln2[3]
> SOLN
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 7 NA 8 NA 9 NA
I need a way to do this over 70,000 times. There is probably an APPLY function I should use, but I do not know what it is. I do have a for loop solution.
> for (i in 1:length(index)){
+ j=index[[i]]
+ print(j)
+ SOLN[,j]=soln2[i]
+ }
[1] 1
[1] 3
[1] 5
> SOLN
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 7 NA 8 NA 9 NA
Any suggestions for a more elegant solution would be appreciated!

Eigenvector Order in R

I am trying to work out an issue regarding the order of eigenvectors returned by eigen in r. Consider the following:
covmatrix <- matrix(data = c(13, 5, 2, 4), nrow = 2, ncol = 2)
covmatrix
eigen <- eigen(covmatrix)
eigen
The output returns:
values
[1] 14 3
vectors
[,1] [,2]
[1,] 0.8944272 -0.1961161
[2,] 0.4472136 0.9805807
Per the documentation, the first column should represent the eigenvector associated with the largest eigenvalue. However, mathematically, when I calculate the eigenvectors I end up with column 2 associated with the eigenvalue 14 as 0.9805807 is 5 times 0.1961161. The math is detailed here. I'm sure I am missing something simple but can't quite work it out.
You are not working with the same matrix. To get consistent result with what you derive analytically, you need
covmatrix <- matrix(data = c(13, 5, 2, 4), nrow = 2, ncol = 2, byrow = TRUE)
eigen(covmatrix)
$values
[1] 14 3
$vectors
[,1] [,2]
[1,] 0.9805807 -0.4472136
[2,] 0.1961161 0.8944272

is it possible to have a matrix of matrices in R?

is it possible to have a matrix of matrices in R? if yes, how should I define such matrix?
for example to have a 10 x 10 matrix, and each element of this matrix contains a matrix itself.
1) list/matrix Yes, create a list and give it dimensions using matrix:
m <- matrix(1:4, 2)
M <- matrix(list(m, 2*m, 3*m, 4*m), 2)
so element 1,1 of M is m:
> M[[1,1]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
2) list/dim<- This also works:
M <- list(m, 2*m, 3*m, 4*m)
dim(M) <- c(2, 2)
3) array This is not quite what you asked for but depending on your purpose it might satisfy your need:
A <- array(c(m, 2*m, 3*m, 4*m), c(2, 2, 2, 2)) # 2x2x2x2 array
so element 1,1 is:
> A[1,1,,]
[,1] [,2]
[1,] 1 3
[2,] 2 4

Resources