r removing symmetrical elements of a matrix - r

I'm trying to combine two adjacency matrices leaving out the symmetric intersections.
M1<-matrix(c(0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0),nrow=5,ncol=5,byrow=T)
M2<-matrix(c(0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0),nrow=5,ncol=5,byrow=T)
The question is : how to reach the matrix below which "forgets" ([1,2],[2,1]) and displays only ones and zeros ?
My final result should be :
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 1 0 0 0 0
[4,] 1 0 0 0 1
[5,] 0 0 0 0 0
I've tried all sorts of additions and substractions involving t(M2) but there is always something wrong.

M = M1+M2
M[M==t(M)]=0
+(M>0)
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 1 0 0 0 0
[4,] 1 0 0 0 1
[5,] 0 0 0 0 0

Thanks to Onyambu. Applying your solution to my MClist of 40 (Mn,Nn) pairs, seems to work in this way:
AddMC<-lapply(1:40, function(x){
(MClist[[x]][[1]]+MClist[[x]][[2]])
})
InterMC<-lapply(1:40, function(x){
AddMC[[x]][AddMC[[x]]==t(AddMC[[x]])]=0
+(AddMC[[x]]>0)
})

Related

How can I make an identical matrix with a column vector?

I have a column vector with dimensions 4000x1, and I need to make a matrix with that vector, but the matrix needs to have the column vector as a diagonal and the other numbers as zero. Something like this:
Column Vector
> vector <- matrix(c(1:5), ncol=1, nrow=5)
> vector
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
Matrix
[,1] [,2] [,3] [,4]
a 1 0 0 0
b 0 2 0 0
c 0 0 3 0
How can I produce this output?
This sounds like the diag() function, e.g.,
> my_vect <- 1:5
> diag(my_vect)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 3 0 0
[4,] 0 0 0 4 0
[5,] 0 0 0 0 5
By the way, as you have written it vector is actually a 5x1 matrix, so you would need to convert it to, well, a vector:
> diag(as.vector(vector))
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 3 0 0
[4,] 0 0 0 4 0
[5,] 0 0 0 0 5

Creating a list of similar diagonal block matrices in R

I have a smaller kxk matrix m given from which I want to create multiple larger NxN diagonal block matrices Q1, Q2, ..., QN. It is ensured that N is always a multiple of k.
A simple example should illustrate better what I mean:
m <- matrix(c(1,3,2,4),2,2) # the small kxk matrix
m
[,1] [,2]
[1,] 1 2
[2,] 3 4
And I want to get for let's say a 6x6 matrix the following diagonal block matrices:
Q1
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 2 0 0 0 0
[2,] 3 4 0 0 0 0
[3,] 0 0 0 0 0 0
[4,] 0 0 0 0 0 0
[5,] 0 0 0 0 0 0
[6,] 0 0 0 0 0 0
Q2
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 0 0 0 0 0
[2,] 0 0 0 0 0 0
[3,] 0 0 1 2 0 0
[4,] 0 0 3 4 0 0
[5,] 0 0 0 0 0 0
[6,] 0 0 0 0 0 0
Q3
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 0 0 0 0 0
[2,] 0 0 0 0 0 0
[3,] 0 0 0 0 0 0
[4,] 0 0 0 0 0 0
[5,] 0 0 0 0 1 2
[6,] 0 0 0 0 3 4
Any ideas how I could achieve this e.g. with lapply such that I can do the same for large matrices?
We can do this with bdiag from Matrix
library(Matrix)
lst <- list(bdiag(m, diag(4)*0), bdiag(0*diag(2), m, 0*diag(2)), bdiag(diag(4)*0, m))
If we want to change it to matrix, then use as.matrix
lapply(lst, as.matrix)
Also, this can be created as a single sparseMatrix
bdiag(list(m, 0*diag(6))[rep(1:2, length.out=5)])

Writing a vector to 3rd dimension of a 3D array in R

I am working on a multi-band Raster image. For the processing Raster is converted to matrix and then pixel wise processed. I am facing problem in writing the pixel values to the blank 3d array which is explained below.
let us assume
I have a blank 3D array
x = array(0,c(4,5,3))
x
, , 1
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
, , 2
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
, , 3
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
and a vector
y = c(5,14)
I want to copy values of y in the 3rd dimension of x so that output look like example given below
x
, , 1
[,1] [,2] [,3] [,4] [,5]
[1,] 5 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
, , 2
[,1] [,2] [,3] [,4] [,5]
[1,] 14 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
, , 3
[,1] [,2] [,3] [,4] [,5]
[1,] NA 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
I have searched on the internet but I am not able to find any solution.

R programming: How to do replace values by row?

How to do a row-wise replacement of values using R?
I have a Matrix and I would like to replace some of its values using an index vector. The problem is that R automatically does a column-wise extraction of the values as opposed to a row-wise.
You will find my code and results below:
Matrix=matrix(rep(0,42),nrow=6,ncol=7,byrow=TRUE)
v=c(1,7,11,16,18)
Matrix[v]=1
Matrix
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 1 0 0 0 0 0
[2,] 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0
[4,] 0 0 1 0 0 0 0
[5,] 0 1 0 0 0 0 0
[6,] 0 0 1 0 0 0 0
What I actually want to get is the row-wise version of this meaning:
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 0 0 0 0 0 1
[2,] 0 0 0 1 0 0 0
[3,] 0 1 0 1 0 0 0
[4,] 0 0 0 0 0 0 0
[5,] 0 0 0 0 0 0 0
[6,] 0 0 0 0 0 0 0
>
Apparently R does a column-wise replacement of values by default.
What is the best way to obtain a row-wise replacement of the values?
Thanks!
You could recalculate the onedimensional indizes to row- and column-indices. Supposing you have calculated the row-indices in the first column of the matrix Ind and the columnindices in the second column of Ind you can do Matrix[Ind] <- 1
Matrix <- matrix(rep(0,42),nrow=6,ncol=7,byrow=TRUE)
v <- c(1,7,11,16,18)
Row <- (v-1) %/% ncol(Matrix) +1
Col <- (v-1) %% ncol(Matrix) +1
Matrix[cbind(Row,Col)] <- 1
Matrix
# [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,] 1 0 0 0 0 0 1
# [2,] 0 0 0 1 0 0 0
# [3,] 0 1 0 1 0 0 0
# [4,] 0 0 0 0 0 0 0
# [5,] 0 0 0 0 0 0 0
# [6,] 0 0 0 0 0 0 0
We can do
+(matrix(seq_along(Matrix) %in% v, ncol=ncol(Matrix), nrow=nrow(Matrix), byrow=TRUE))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#[1,] 1 0 0 0 0 0 1
#[2,] 0 0 0 1 0 0 0
#[3,] 0 1 0 1 0 0 0
#[4,] 0 0 0 0 0 0 0
#[5,] 0 0 0 0 0 0 0
#[6,] 0 0 0 0 0 0 0
You could redo your 1's to make them row-wise or you can do the following:
Matrix=matrix(rep(0,42),nrow=6,ncol=7,byrow=TRUE)
v=c(1,7,11,16,18)
Matrix<-t(Matrix)
Matrix[v]=1
Matrix<-t(Matrix)
Matrix
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 0 0 0 0 0 1
[2,] 0 0 0 1 0 0 0
[3,] 0 1 0 1 0 0 0
[4,] 0 0 0 0 0 0 0
[5,] 0 0 0 0 0 0 0
[6,] 0 0 0 0 0 0 0

R recursively run an unknown sized nested loop

I am not sure if this is possible, but I thought I might post it anyway. Currently I am trying to write a code that will run a nested sort. The problem is, I don't know how many nested loops will need to run, it can vary from 2-7 sorting criteria.
Each loop of the function creates a data set that the lower loops will then use. I know this needs to be done using recursion, but I am having an extremely hard time getting this to work. Any help would be appreciated!
library(abind)
re <- c(5,5,5)
answer = matrix(0,5,5)
for(a in 1:4){
answer <- abind(answer,matrix(0,5,5),along=3)
}
for( i in 1:re[1]){
first <- c(1:re[1])
for(j in 1:re[2]){
if(j %in% first == 1){
second = j
}
print(second)
for(k in 1:re[3]){
if(k == second){
answer[k,j,i] <- k
}
}
}
}
answer
Output
answer
, , 1
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 3 0 0
[4,] 0 0 0 4 0
[5,] 0 0 0 0 5
, , 2
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 3 0 0
[4,] 0 0 0 4 0
[5,] 0 0 0 0 5
, , 3
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 3 0 0
[4,] 0 0 0 4 0
[5,] 0 0 0 0 5
, , 4
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 3 0 0
[4,] 0 0 0 4 0
[5,] 0 0 0 0 5
, , 5
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 3 0 0
[4,] 0 0 0 4 0
[5,] 0 0 0 0 5

Resources