R: extract parts of matrices in loops - loop only run once - r

I am not an advanced user, but I have been trying to solve this problem for many hours now and I do not know how else to proceed.
SETTING: I have a 2X10000 matrix, which is constituted of 10000 repetitions of 2 variables, call them a and b,in row 1 and 2 respectively.
I need an operation repeated for every column (i.e. 10000 times), hence the loop.
The operation is the following:
for every column [a b]', create a 2x2 matrix looking like this:
[a b]
[b a]
then transpose this matrix and multiply it by the original column column. At the end I should obtain, for each original column [a b]', another column but with two different values.
I build the 2x10000 matrix to contain the result:
R <- 10000
a <- matrix(rep(1, 200), nrow=2, ncol=R)
Gamma is the 2x10000 matrix whose columns I am using. Then I apply the following loop:
for (j in 1:R) {
Big_Gamma = matrix(c(Gamma[1, j], Gamma[2, j], Gamma[2, j], Gamma[1, j]), nrow=2, ncol=2);
a <- solve(Big_Gamma)%*%Gamma[, j];
}
Big_Gamma is the 2x2 matrix I need to invert and multiply by the original vector.
Again, I need this done for each of the 10000 vectors and I need another vector (of equal dimension as the original one) as output (if possible).
I tried different specifications, also in the way I extract the columns, but it always only runs once (i.e. the matrix a changes and becomes a 2x1 one)
I have looked for hours on various sites and could not find an answer. I hope the question is not too stupid.
Thank you in advance, soo much!

You are overwriting a on each iteration. Try:
R <- 10000
a <- matrix(rep(1, 200), nrow=2, ncol=R)
for (j in 1:R) {
Big_Gamma = matrix(c(Gamma[1, j], Gamma[2, j], Gamma[2, j], Gamma[1, j]), nrow=2, ncol=2);
a[, j] <- solve(Big_Gamma)%*%Gamma[, j];
}

Related

Faster method of counting specified values from rows in large matrix in R

MC is a very large matrix, 1E6 rows (or more) and 500 columns. I am trying to get the number of occurrences of the values 1 through 13 for each of the columns. Sometimes the number of occurrences for one of these values will be zero. I would like my final output to be a 300X13 matrix (or data frame) with these count values. I am wondering if anyone can suggest a more efficient manner then what I currently have, which is the following:
MCct<-matrix(0,500,13)
for (j in 1:500){
for (i in 1:13){
MCct[j,i]<-length(which(MC[,j]==i))}}
I don't that table works, because I need to also know if zero occurrences occurred...I couldn't figure it out how to do that if it is possible. And I am only somewhat familiar with apply, so maybe there is a method to use that...I haven't been successful in figuring that out yet.
Thanks for the help,
Vivien
You could do this with sapply (to iterate from 1 to 13) and colSums (to add up the columns of j):
MCct <- sapply(1:13, function(i) {
colSums(MC == i)
})
Suppose you have a set of values you're interested in
set <- 1:4
n = length(set)
and you have a matrix that includes those values, and others
m <- matrix(sample(10, 120, TRUE), 12, 10)
Create a vector indicating the index in the set of each matching value
idx <- match(m, set)
then make the index unique to each column
idx <- idx + (col(m) - 1) * n
idx ranges from 1 (occurrences of the first set element in the first column) to n * ncol(m) (occurrence of the nth set element in the last column of m). Tabulate the unique values of idx
v <- tabulate(idx, nbin = n * ncol(m))
The first n elements of v summarize the number of times set elements 1..n appear in the first column of m. The second n elements of v summarize the number of times set elements 1..n appear in the second column of m, etc. Reshape as the desired matrix, where each row represents the corresponding member of the set.
matrix(v, ncol=ncol(m))
table can count zero occurrences, you just need to create a factor that has the whole range of levels, e.g.
apply(MC, 2, function(x) table(factor(x, levels=1:13)))
This is not as efficient as #Patronus' solution though.

Creating multiple matrices with a for loop

I would like to create ncol(y) number of matrices taking each column from y matrix and replicating it rep number of times. I am not doing the for loop right though. To reiterate, below I would like to get three separate matrices, the first one would have values of 1 to 100 repeated 200 times (they come from the first columns of y), second would have vector 101-200 repeated 200 times (2nd column of y) as well and the third one would have values 201-300 repeated 200 times (3rd column of y). Preferably the output name would be matrix1, matrix2 or a list.
y <- matrix(1:300,100,3)
rep = 200
for (i in 1:ncol(y)) {
newmatrix <- replicate(rep,y[,i])
valuematrix[[i]] <- newmatrix
}
You're missing the initialization of valuematrix. You can do this through
valuematrix <- list()
just before the for loop.
You might also consider using lapply to solve this problem. It automatically stores the matrices in a list.
y <- matrix(1:300, 100, 3)
rep = 200
matList <- lapply(1:ncol(y), function(i) replicate(rep, y[,i]))

Matrix multiplication using variable element producing Error non-conformable arguments

I am a newbie to R, but avid to learn.
I have been trying endlessly to create a matrix with a variable element (in this case [2,2]). The variable element should take number 4 on the first run and 5 on the second (numbers).
This matrix would be multiplied by another matrix (N0) and produce a result matrix (resul).
Up so far, I have only been able to create the initial matrix with the variable element using a for loop, but I am having problems indexing the result matrix. I have tried several versions, but this is the latest. Any suggestions would be greatly appreciated. Thank you.
numbers <- c(4,5,length.out = 2)
A <- matrix(c(1,2,3,NA),nrow=2,ncol=2)
resul <- matrix(nrow=2,ncol=1)
for (i in 1:2) {
A[2,2]<- matrix(numbers[i])
N0 <- matrix(c(1,2),nrow=2,ncol=1)
resul[i,]<- A[i,i]%*%N0
}
Your code has two distinct problems. the first is that A[i,i] is a 1 x 1
matrix, so you're getting an error because your multiplying a 1 x 1 matrix
by a 2 x 1 matrix (N0).
you could either drop the subscript [i,i] and initialize the result to be
a two by two matrix like so:
result <- matrix(nrow=2,ncol=1)
for (i in 1:2){
A[2,2]<- matrix(numbers[i])
# a colunm vector
N0 <- matrix(c(1,2),
nrow=2,
ncol=1)
# note the index is on the column b/c `A%*%N0` is a column matrix
result[,i]<- A%*%N0
}
or you could either drop the the second subscript [i,] and initialize the result to be
a two by two matrix like so:
result <- matrix(nrow=2,ncol=1)
for (i in 1:2){
A[2,2]<- matrix(numbers[i])
# a colunm vector
N0 <- matrix(c(1,2),
nrow=2,
ncol=1)
result[i,]<- A[i,]%*%N0
}
but it's not clear from you post which (if either) answer is the correct one. Indexing is tricky :)

R how to do a for loop and multiply each row in a specific matrix to a column (and they display results)?

Let's say I have matrix a which is 10x10 (10 rows) and matrix b which is 10x1 (column)
and I want to multiply each row of a with b, so the end result would be a column of 10 elements.
for(i in 1:nrow(a)) a[i,] %*% b[,1]
I have something like the above right now
1) Is this correct?
2) How do I get it to display on screen?
Thank you, please keep in mind I'm a beginner with R. :)
Close! In this case, you can simply do
c <- a %*% b
The operator %*% is actual matrix multiplication. For more on this consult the help page using
?`%*%`

lapply function with 2 count variables

I am very green in R, so there is probably a very easy solution to this:
I want to calculate the average correlation between the column vectors in a square matrix:
x<-matrix(rnorm(10000),ncol=100)
aux<-matrix(seq(1,10000))
loop<-sapply(aux,function(i,j) cov(x[,i],x[,j])
cor_x<-mean(loop)
When evaluating the sapply line I get the error 'subscript out of bounds'. I know I can do this via a script but is there any way to achieve this in one line of code?
No need for any loops. Just use mean(cov(x)), which does this very efficiently.
The problem is due to aux. The variable auxhas to range from 1 to 100 since you have 100 columns. But your aux is a sequence along the rows of x and hence ranges from 1 to 10000. It will work with the following code:
aux <- seq(1, 100)
loop <- sapply(aux, function(i, j) cov(x[, i], x[, j]))
Afterwards, you can calculate mean covariance with:
cor_x <- mean(loop)
If you want to exclude duplicate fields (e.g., cov(X,Y) is inherently identical to cov(Y,X)), you can use:
cor_x <- mean(loop[upper.tri(loop, diag = TRUE)])
If you also want to exclude cov(X,X), i.e., variance, you can use:
cor_x <- mean(loop[upper.tri(loop)])

Resources