I've got a large nxn matrix and would like to take off-diagonal slices of varying sizes. For example:
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
I'd like an R function which, when given the matrix and "width of diagonal slice" would return an nxn matrix of just those values. So for the matrix above and, say, 3, I'd get:
1 x x x x x
1 2 x x x x
1 2 3 x x x
x 2 3 4 x x
x x 3 4 5 x
x x x 4 5 6
At the moment I'm using (forgive me) a for loop which is incredibly slow:
getDiags<-function(ndiags, cormat){
resmat=matrix(ncol=ncol(cormat),nrow=nrow(cormat))
dimnames(resmat)<-dimnames(cormat)
for(j in 1:ndiags){
resmat[row(resmat) == col(resmat) + j] <-
cormat[row(cormat) == col(cormat) + j]
}
return(resmat)
}
I realise that this is a very "un-R" way to go about solving this problem. Is there a better way to do it, probably using diag or lower.tri?
D = diag( v ) returns a square diagonal matrix with the elements of vector v on the main diagonal. D = diag( v , k ) places the elements of vector v on the k th diagonal. k=0 represents the main diagonal, k>0 is above the main diagonal, and k<0 is below the main diagonal.
If x is a matrix then diag(x) returns the diagonal of x . The resulting vector will have names if the matrix x has matching column and row names. If x is a vector (or a 1-d array) then diag(x) returns a diagonal matrix whose diagonal is x .
In a table of numbers that has the same number of rows as columns, the entries that are not in the Main Diagonal are referred to as the off-diagonal entries in the table.
An element aij of a matrix A = [aij] is a diagonal elements of matrix if i = j, such as when rows and column suffixes are equal. Thus, a11 , a22 , a33, a44, … so on are diagonal elements of the matrix A = [aij]. The principal diagonal is also known as the leading diagonal.
size <- 6
mat <- matrix(seq_len(size ^ 2), ncol = size)
low <- 0
high <- 3
delta <- rep(seq_len(ncol(mat)), nrow(mat)) -
rep(seq_len(nrow(mat)), each = ncol(mat))
#or Ben Bolker's better alternative
delta <- row(mat) - col(mat)
mat[delta < low | delta > high] <- NA
mat
this works with 5000 x 5000 matrices on my machine
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With