how to find a triangular matrix by permutation - r

I have a square matrix which I know can become a triangular one by permutation, what would be the Matrix::function call to get the triangular one ?
I have thus B as
B <- matrix(c(0,5,6,1,2,3,0,0,9),3,3)
and want to get a function that renders as result
B[,c(2,1,3)]

You could try with
B[, order(sapply(1:ncol(B), function(x) rle(B[,x]==0)$lengths[1]*rle(B[,x]==0)$values[1]))]
# [,1] [,2] [,3]
#[1,] 1 0 0
#[2,] 2 5 0
#[3,] 3 6 9
This orders the columns of the matrix according to the number of consecutive zeros (counted from the top row downwards), with the shortest sequence of zeros first.

Related

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.

Delete specific values in a matrix according to two position vectors

My aim is to delete specific positions in a matrix according to a vector. Just giving you a small example.
Users_pos <- c(1,2)
Items_pos <- c(3,2)
Given a Matrix A:
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
My aim according to the two Vectors User_pos and Item_pos is to delete the following values
A[1,3] and A[3,2]
I'm wondering if there's a possibility to do so without typing in the values for rows and columns by hand.
You can index k elements in a matrix A using A[X], where X is a k-row, 2-column matrix where each row is the (row, col) value of the indicated element. Therefore, you can index your two elements in A with the following indexing matrix:
rbind(Users_pos, Items_pos)
# [,1] [,2]
# Users_pos 1 2
# Items_pos 3 2
Using this indexing, you could choose to extract the information current stored with A[X] or replace those elements with A[X] <- new.values. If you, for instance, wanted to replace these elements with NA, you could do:
A[rbind(Users_pos, Items_pos)] <- NA
A
# [,1] [,2] [,3]
# [1,] 1 NA 3
# [2,] 4 5 6
# [3,] 7 NA 9

Efficient creation of tridiagonal matrices

How can I create a quadratic band matrix, where I give the diagonal and the first diagonal below and above the diagonal? I am looking for a function like
tridiag(upper, lower, main)
where length(upper)==length(lower)==length(main)-1 and returns, for example,
tridiag(1:3, 2:4, 3:6)
[,1] [,2] [,3] [,4]
[1,] 3 1 0 0
[2,] 2 4 2 0
[3,] 0 3 5 3
[4,] 0 0 4 6
Is there an efficient way to do it?
This function will do what you want:
tridiag <- function(upper, lower, main){
out <- matrix(0,length(main),length(main))
diag(out) <- main
indx <- seq.int(length(upper))
out[cbind(indx+1,indx)] <- lower
out[cbind(indx,indx+1)] <- upper
return(out)
}
Note that when the index to a matrix is a 2 column matrix, each row in that index is interpreted as the row and column index for a single value in the vector being assigned.

Raising the entries of a matrix by column

I need to create a function (x,k), were x= vector of length n, and k=integer.
The function needs to give me a matrix of dimensions [n x k], and the entries in each column need to be raised to the power of the number of that column (ie. in column one the entries are x, in column 2 the entries are x^2, etc).
I'm having a hard time figuring it out how to structure a function that would do this type of operation by column.
Thank you so much.
Something like this probably, taking advantage of outer, which returns a matrix as a result of applying a function to the two vectors.
matpower <- function(x,k) outer(x,seq_len(k),`^`)
matpower(1:4,4)
# [,1] [,2] [,3] [,4]
#[1,] 1 1 1 1
#[2,] 2 4 8 16
#[3,] 3 9 27 81
#[4,] 4 16 64 256

How to replace non-diagonal elements in a matrix?

More specifically, I want all elements other than the diagonal ones (X_11, X_22, X_33,...,X_jj) to be zero.
E.g. I want:
[1 4 5
2 3 5
3 9 8]
to be:
[1 0 0
0 3 0
0 0 8]
Is this possible? Sorry I'm a complete noob at this..
It's a simple one liner. First, get the data in:
> (a <- matrix(scan(),nr=3,byrow=TRUE))
1: 1 4 5 2 3 5 3 9 8
10:
Read 9 items
[,1] [,2] [,3]
[1,] 1 4 5
[2,] 2 3 5
[3,] 3 9 8
Method 1:
> diag(diag(a))
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 3 0
[3,] 0 0 8
The thing is, if its argument is a matrix, diag extracts the diagonal... but if the argument is a vector, it's a function that creates a diagonal matrix. So just use it twice. (In fact diag has four different uses, depending on what you give it, though two of the cases are quite similar.) See ?diag
If your matrices are huge this isn't likely to be the most efficient way, but for moderate size cases that's the way I do it.
---
Method 2:
A completely different one-liner that also works -
ifelse(row(a)==col(a),a,0)
The two work the same on square matrices. But they have a different result on non-square matrices - the first one returns a square matrix (of dimension the smaller of the two original dimensions), while the second one returns an object of the same shape as its argument; this can be useful depending on the situation.
The simplest way to do this, is to create a new matrix filled with 0s, then replace its diagonal with the diagonal of the old matrix.
So if you have:
m <- cbind(c(1,2,3), c(4,3,9), c(5, 5, 8)) # The original matrix
diagonal <- diag(m)
m <- matrix(0, nrow(m), ncol(m)) # Overwrite the old matrix
diag(m) <- diagonal
For a matrix of n x m
for i to n
for j to m
if i != j
matrix[i][j] = 0;
If m is your matrix try:
m = matrix(c(1,4,5,2,3,5,3,9,8),3,3)
m[upper.tri(m) | lower.tri(m)] = 0
m
## [,1] [,2] [,3]
## [1,] 1 0 0
## [2,] 0 3 0
## [3,] 0 0 8
It simply dependes on the size of the matrix you're dealing with, let's say you have a nxn matrix then the diagonals are gonna be at these places 0, n+1 , 2(n+1), 3(n+1),... if your matrix as you mentioned is not multi dimensional and is linear! so by simply writing a for loop it is possible.
I'm transferring my answer from your second post on this topic.
You can use the following to compute a logical matrix which describes the non-diagonal entries of a n×n matrix:
outer(1:n, 1:n, function(i,j) i!=j)
Applied to your example:
> m <- matrix(c(1,2,3,4,3,9,5,5,8),ncol=3)
> m
[,1] [,2] [,3]
[1,] 1 4 5
[2,] 2 3 5
[3,] 3 9 8
> m[outer(1:3, 1:3, function(i,j) i!=j)] <- 0
> m
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 3 0
[3,] 0 0 8
I also like the triangle approach by #e4e5f4. That might be a bit faster than this code here, but this code here might be easier to adapt to different situations. So it's good to know this one, even if that one might be preferrable for your current application.

Resources