Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a Triangular Matrix from a Vector performing sequential operations

I have been trying to solve the following problem.

Suppose I have the following vector:

aux1<-c(0,0,0,4,5,0,7,0,0,10,11,12) where the numbers represent the number of the row.

I want to calculate the distance between the differents elements of this vector fixing the first component, then the second and so on.

If the element is zero, I do not want to count it, so I put a NA instead. The output I want should look like this:

NA  NA  NA  NA  NA
NA  NA  NA  NA  NA
NA  NA  NA  NA  NA
NA  NA  NA  NA  NA
1   NA  NA  NA  NA
NA  NA  NA  NA  NA
3   2   NA  NA  NA
NA  NA  NA  NA  NA
NA  NA  NA  NA  NA
6   5   3   NA  NA
7   6   4   1   
8   7   5   2   1

In the first column, I have the difference between the first element different from zero and all other elements, i.e., Matrix[5,1]=5-4=1 and Matrix[12,1]=12-4=8. Also, Matrix[7,2]=7-5=2, where 5 is the second element in the vector non-equal to zero. Notice that Matrix[10,3]=10-7=3, where 7 is third element non-equal to zero, but the seventh element in my vector.

I have tried to do this in a loop. My current code looks like this:

M=matrix(nrow=N-1, ncol=N-1))

for (i in 1:N-1){
  for (j in 1:N-1){
    if(j<=i)
      next
    else
      if(aux1[j]>0)
      M[j,i]=aux1[j]-aux1[i]
      else
        M[j,i]=0
  }
}

Unfortunately. I have not been able to solve my problem. Any help would be greatly appreciated.

like image 706
ju.arroyom Avatar asked Jun 15 '15 21:06

ju.arroyom


People also ask

What is triangular matrix with example?

An upper triangular matrix is a triangular matrix with all elements equal to below the main diagonal. It is a square matrix with element aij where aij = 0 for all j < i. Example of a 2×2matrix. (1203) Example of a 3×3matrix.


2 Answers

You could try something like the following (with generous help from @thela)

res <- outer(aux1, head(aux1[aux1 > 0], -1), `-`)
is.na(res) <- res <= 0 
#       [,1] [,2] [,3] [,4] [,5]
#  [1,]   NA   NA   NA   NA   NA
#  [2,]   NA   NA   NA   NA   NA
#  [3,]   NA   NA   NA   NA   NA
#  [4,]   NA   NA   NA   NA   NA
#  [5,]    1   NA   NA   NA   NA
#  [6,]   NA   NA   NA   NA   NA
#  [7,]    3    2   NA   NA   NA
#  [8,]   NA   NA   NA   NA   NA
#  [9,]   NA   NA   NA   NA   NA
# [10,]    6    5    3   NA   NA
# [11,]    7    6    4    1   NA
# [12,]    8    7    5    2    1
like image 191
David Arenburg Avatar answered Sep 28 '22 11:09

David Arenburg


Using sapply and ifelse :

sapply(head(vv[vv>0],-1),function(y)ifelse(vv-y>0,vv-y,NA))

You loop over the positive values (you should also remove the last element), then you extract each value from the original vector. I used ifelse to replace negative values.

#       [,1] [,2] [,3] [,4] [,5]
#  [1,]   NA   NA   NA   NA   NA
#  [2,]   NA   NA   NA   NA   NA
#  [3,]   NA   NA   NA   NA   NA
#  [4,]   NA   NA   NA   NA   NA
#  [5,]    1   NA   NA   NA   NA
#  [6,]   NA   NA   NA   NA   NA
#  [7,]    3    2   NA   NA   NA
#  [8,]   NA   NA   NA   NA   NA
#  [9,]   NA   NA   NA   NA   NA
# [10,]    6    5    3   NA   NA
# [11,]    7    6    4    1   NA
# [12,]    8    7    5    2    1
like image 29
agstudy Avatar answered Sep 28 '22 11:09

agstudy