Subtract the previous value within a row and accumulate it in another matrix in R

1

My intention is for a given matrix, go through the row and each value [i,j] subtract the value [i,j-1] . Once traveled, if the value is negative, it accumulates it in [i,2] and if it is positive in [i,1] .

Here's an example:

A,B,C,D,E,F
(0,1,3,2,4,5)
(2,9,7,3,4,6)
(5,9,4,3,0,1)

the result I hope it is the sum of doing (example only with row1):

row1: 1-0=0; 3-1=2; 2-3= -1; 4-2=2; 5-4=1

X,Y
(5, -1)
(10, -6)
(5, -9)

I hope you can help me.

    
asked by Hugo_p 25.09.2017 в 17:57
source

1 answer

0

Using loop as you ask, it can be resolved in the following way:

m <- matrix( c(0,1,3,2,4,5,2,9,7,3,4,6,5,9,4,3,0,1), ncol=6, byrow=TRUE)
m

new_m <- matrix(nrow=nrow(m), ncol=2)

for (row in c(1:nrow(m))){
    new_row <- c()
    for (col in c(2:ncol(m))){
        new_row <- c(new_row, m[row, col]- m[row,col-1])
        new_m[row, 1] <- sum(new_row[new_row>0])
        new_m[row, 2] <- sum(new_row[new_row<0])
    }
}

new_m

The initial matrix would be this:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0    1    3    2    4    5
[2,]    2    9    7    3    4    6
[3,]    5    9    4    3    0    1

And the final result:

     [,1] [,2]
[1,]    6   -1
[2,]   10   -6
[3,]    5   -9

Check the first row of your expected result, because it is not 5 but 6.

The loops usually have a negative impact in terms of performance, so if possible, it may be convenient to work directly on the objects and not have to iterate over each row / column. The following is a more compact way to solve your question

m <- matrix( c(0,1,3,2,4,5,2,9,7,3,4,6,5,9,4,3,0,1), ncol=6, byrow=TRUE)
m

final <- m[,-1] - m[,-ncol(m)] 
new_m <- matrix(c(rowSums(final * as.numeric(final>0)),rowSums(final * as.numeric(final<0))), ncol=2) 
new_m

Explanation:

  • m[,-1] - m[,-ncol(m)] subtracts two versions of the same matrix, the first without the first column and the second without the last, this is basically subtracting one cell for the previous one in each row. We are left with a matrix that has one less column that we will not use

         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    2   -1    2    1
    [2,]    7   -2   -4    1    2
    [3,]    4   -5   -1   -3    1
    
  • Finally matrix(c(rowSums(final * as.numeric(final>0)),rowSums(final * as.numeric(final<0))), ncol=2) generates a new matrix with the sum of the rows ( rowSums ) whose values are positive and whose values are negative.

answered by 25.09.2017 / 20:32
source