Calculations between matrices in r - r

I have a question related to working on two matrices.
Let's assume that first matrix (P(i)) is:
x <- rmultinom(2, size = 10, prob=c(0.5,0.5))
> x
[,1] [,2]
[1,] 6 4
[2,] 4 6
..and the second matrix (Q(i)) is:
y <- rmultinom(2, size = 10, prob=c(0.5,0.5))
> y
[,1] [,2]
[1,] 6 7
[2,] 4 3
Let's assume that P(i) stands for every cell in the first matrix and Q(i) stands for every cell in the second matrix. I am trying to sum this function, (I could not find the symbol for the "Sum"):
z = (Sum)(P(i)*log(P(i)/Q(i)))
Any help would be greatly appreciated.
Thanks!

Related

How to compare and find the min between a constant and each element of a matrix?

For example, I have a 3x3 matrix called "A" with numbers between 1 to 10, and a constant= 5. I would like to create another matrix 3x3 called "B" where each element is the minimum between A elements and the constant.
I know i could do this easily with for loops, but is there any function or shorter way to do this?
example
A[1,1] = 2 -> B[1,1]=min(A[1,1],constant) ->B[1,1]=2
A[1,2]=10 -> B[1,2]=min(A[1,2],constant) ->B[1,2]=5
You can use pmin :
set.seed(123)
A <- matrix(sample(1:10, 9), nrow = 3)
constant <- 5
pmin(A, constant)
# [,1] [,2] [,3]
#[1,] 3 5 1
#[2,] 5 5 5
#[3,] 2 5 5

How to update matrix value in R based on comparison of two matrix?

How to generate a matrix based on a comparison of two matrices. I have (column,row) matrix A (10,1) and B (10, 100). Matrix A is compared to each row of matrix B if the value of B is smaller than A then value B is updated to a value of A.
n.units<-100
n.option<-10
A<-rnorm(n.option,1,0.2)
B<-matrix(rnorm(n.option*n.units,1,0.2)n.col=n.units)
renew <-function(){Thresholds=obj.value }
update1 <- apply((Thresholds < obj.value),1,renew)
I am new to R programming, please give some advice to solve it.
I guess what you are trying can be achieved with pmax. Try
pmax(B, A)
You have a numeric vector A which is compared with matrix B. 1st element of A is compared with first row of B and the maximum value is selected. Same goes for all other rows since pmax recycles the shorter vector to the longer vector length. Also note that pmax(B, A) gives different structure than pmax(A, B) although the value is the same.
Just to make it easier to understand, consider this example
mat <- matrix(1:10, ncol = 5)
mat
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 3 5 7 9
#[2,] 2 4 6 8 10
pmax(mat, c(3, 7))
# [,1] [,2] [,3] [,4] [,5]
#[1,] 3 3 5 7 9
#[2,] 7 7 7 8 10
Here 1st row is compared with 3 and second row is compared with 7 and maximum value is selected.

Avoid the for loop

I would like to compute the product between the each row of a matrix x with itself. And then sum the result of all these products. The result is a scalar. I make the following coda that works but is not efficient. Can someone help me to avoid the for loop?
for(i in 1:nrow(x){
resid2[i] <- t(x[i,])%*% x[i,]
}
V = sum(resid2)/
The solution is just the sum of squares of all elements of the matrix.
V = sum(x^2)
which can also be calculated via matrix multiplication as:
V = crossprod(as.vector(x))
The intermediate vector resid2 can be calculated as
resid2 = rowSums(x^2)
V = sum(resid2)
Here is an answer that swaps the for loop out for the apply family.
sum(apply(x, margin = 1, function(z) z%*%z))
The apply function takes the matrix x, margin = 1 means for each row (as opposed to margin = 2 which means each column). So, for each row in x run a function that multiplies that row by itself: function(z) z%*%z
If I understand you correctly, you don't need to loop at all. mat %*% mat should do it:
mat <- matrix(seq.int(9), nrow=3)
mat
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
mat %*% mat
## [,1] [,2] [,3]
## [1,] 30 66 102
## [2,] 36 81 126
## [3,] 42 96 150

Strange behavior of apply/ reverse function in R

I have a simple matrix:
mat = rbind(c(1:3),c(4:6),c(7:9))
mat
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# [3,] 7 8 9
I want to now reverse the matrix row-wise. That is I want to obtain:
revMat
# [,1] [,2] [,3]
# [1,] 3 2 1
# [2,] 6 5 4
# [3,] 9 8 7
To do this I tried
apply(mat, 1, rev)
And the result was:
# [,1] [,2] [,3]
# [1,] 3 6 9
# [2,] 2 5 8
# [3,] 1 4 7
I find this to be extremely strange. It's like the rows are reversed and then the final matrix is transposed. I don't understand why. If I try simply, for instance,
apply(mat, 2, rev)
it gives me the expected reversal of each column
# [,1] [,2] [,3]
# [1,] 7 8 9
# [2,] 4 5 6
# [3,] 1 2 3
Therefore to obtain the final result I have to perform
t(apply(t(bg), 2, rev))
Thus obtaining the required matrix is NOT a problem for me, but I don't understand the "anomaly" in the behavior of apply/ reverse. Can anyone explain this to me?
Edit: To make clear the distinction, I already know how to do the reversal. I want to know WHY this happens. How to is clear from many earlier questions including
How to reverse a matrix in R?
apply always puts the result in the first dimension. See ?apply for more information. Assuming this input:
mat <- matrix(1:9, 3, byrow = TRUE)
here are some alternatives:
1) transpose
t(apply(mat, 1, rev))
2) avoid apply with indexing
mat[, 3:1]
3) iapply An idempotent apply was posted here:
https://stat.ethz.ch/pipermail/r-help/2006-January/086064.html
Using that we have:
iapply(mat, 1, rev)
There was also an idempotent apply, iapply, in version 0.8.0 of the reshape package (but not in the latest version of reshape): https://cran.r-project.org/src/contrib/Archive/reshape/
4) rollapply rollapply in the zoo package can be used:
library(zoo)
rollapply(mat, 1, rev, by.column = FALSE)
5) tapply The tapply expression here returns a list giving us the opportunity to put it together in the way we want -- in this case using rbind:
do.call("rbind", tapply(mat, row(mat), rev))
6) multiply by a reverse diagonal matrix Since rev is a linear operator it can be represented by a matrix:
mat %*% apply(diag(3), 1, rev)
or
mat %*% (row(mat) + col(mat) == 3+1)
If you look at the help for apply(), this is exactly the behavior you would expect:
Value
If each call to FUN returns a vector of length n, then apply returns
an array of dimension c(n, dim(X)[MARGIN]) if n > 1.
a nice option to do what you want is to use indexing:
mat[,ncol(mat):1]

Loop Matrix to store in Cube

I want to loop an equation through a matrix and store the results in a cube, so that Cube[,,1] is one result of the matrix.
I currently have written the following
PercentileReturn <- array(NA, c(RetAge,length(Percentile)+1,nrow(Demo)))
for (i in 1:nrow(Demo)) {
PercentileReturn[,,i] <-
PercentileReturn[Demo[i,3]:RetAge,
1:length(Percentile),1]<-
t(apply((apply(AnnualReturns[(Demo[i,3]):RetAge,],2,cumprod)) *
Demo[i,4],1,function(x){quantile(x, Percentile, na.rm=T)}))
}
and it results in the following error
Error in PercentileReturn[, , i] <- PercentileReturn[Demo[i, 3]:RetAge, :
number of items to replace is not a multiple of replacement length
I assume it's because the Matrix I am trying to plug in isn't in 3 dimensions.
Basically a stripped down version would be to have an
array(NA,c(2,2,3)) populated with a matrix times a vector
so that say
Matrix * vector c(1,2,3)
[,1] [,2]
[1,] 4 4
[2,] 4 4
would result in the following cube
, , 1
[,1] [,2]
[1,] 4 4
[2,] 4 4
, , 2
[,1] [,2]
[1,] 8 8
[2,] 8 8
, , 3
[,1] [,2]
[1,] 12 12
[2,] 12 12
That will do it:
M <- matrix(1:4,2) # in your example M <- matrix(4, 2,2)
x <- 1:3
array(sapply(x, function(xi) M*xi), c(dim(M), length(x)))
I found the error the first
PercentileReturn[,,i]
has to also match the dimensions of the loop data below written as
PercentileReturn[Demo[i,3]:RetAge,1:length(Percentile),i]
Thanks Jogo, I will be using something similar to what you wrote in another issue down the line.

Resources