sum vectors in a matrix by distance from a cell (R)

Viewed 232

Suppose I have a matrix A of dimensions n x m. A starting cell (i,j), And a constant k which satisfies k < n x m.

I need a way to extract the values inside A such that all values are within k steps from the starting cell. a step is either a column move or a row move. Then Im looking to sum the extracted values by 2 groups where 1 group consists of sums obtained from the same column in the original matrix and the other group is the sum obtained from summation of values along rows of the original matrix.

It is important for me that this addresses situations where the starting cell is within k steps from the edge of the matrix. Example set (I'm heavily simplifying here):

> #create matrix where m = 7,n = 7
> Mat <- sample(1:49,49) %>% matrix(7,7)
> 
> #declare starting cell where (i = 4, j = 2)
> i = 4
> j = 2
> 
> #declare number of steps
> k = 2
> 
> Mat
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]   25   35   29   10   16   46   23
[2,]   32   43    7    5   31    1   14
[3,]   36   19   49   45   13   41   47
[4,]   17   18   48    9    3   28   12
[5,]   26    6   30   33   20    2   11
[6,]   40   24   39   21   37   38    8
[7,]    4   15   34   22   27   44   42
> Mat[i,j]
[1] 18

for this example an output would be two vectors (one for column sums and one for row sums):

> Columnsum  <- c(sum(36,17,26) ,           #sum(Mat[3:5,1])
+                 sum(43,19,18,6,24),       #sum(Mat[2:6,2])
+                 sum(49,48,30),            #sum(Mat[3:5,3])
+                 sum(9))                   #sum(Mat[4:4,3])
> 
> Rowsum <- c(sum(43),                       #sum(Mat[2,2:2])
+             sum(36,19,49),                 #sum(Mat[3,1:3])
+             sum(17,18,48,9),               #sum(Mat[4,1:4])
+             sum(26,6,30),                  #sum(Mat[5,1:3])
+             sum(24))                       #sum(Mat[6,2:2])
>             
> Columnsum
[1]  79 110 127   9
> Rowsum
[1]  43 104  92  62  24
1 Answers

You could 'remove' parts of your matrix Mat with entries more than k steps away from (i,j) by overwriting them with NA:

Mat[abs(row(Mat) - i) + abs(col(Mat) - j) > k] <- NA

Then remove the rows and columns that are entirely NA:

Mat <- Mat[rowSums(is.na(Mat)) != ncol(Mat), colSums(is.na(Mat)) != nrow(Mat)]

And finally you can compute the row and column sums:

Columnsum <- colSums(Mat, na.rm = TRUE)
Rowsum <- rowSums(Mat, na.rm = TRUE)
Related