loki loki - 3 months ago 8
R Question

Minimum of cells in two matrices within a moving kernel

I have two matrices

m1
and
m2
.

m1 <- matrix(1:16, ncol = 4)
m2 <- matrix(16:1, ncol = 4)
# > m1
# [,1] [,2] [,3] [,4]
# [1,] 1 5 9 13
# [2,] 2 6 10 14
# [3,] 3 7 11 15
# [4,] 4 8 12 16

# > m2
# [,1] [,2] [,3] [,4]
# [1,] 16 12 8 4
# [2,] 15 11 7 3
# [3,] 14 10 6 2
# [4,] 13 9 5 1


I want to find the minimum between the two matrices for each cell within a moving kernel of 3x3. The outer margines should be ignored, i.e. they can be filled with
NAs
and the
min
function should then have
na.rm = TRUE
. The result should look like this:

# > m3
# [,1] [,2] [,3] [,4]
# [1,] 1 1 3 3
# [2,] 1 1 2 2
# [3,] 2 2 1 1
# [4,] 3 3 1 1


I have already tried a combination of
pmin{base}
and
runmin{caTools}
like this:

pmin(runmin(m1, 3, endrule = "keep"),
runmin(m2, 3, endrule = "keep"))


However, this did not work. Probably due to the fact that


"If x is a matrix than each column will be processed separately."
(from
?runmin
)


Is there any package, that performs such operations, or is it possible to
apply
?

Answer

Here is a base R approach:

m    = pmin(m1, m2)
grid = expand.grid(seq(nrow(m)), seq(ncol(m)))

x = apply(grid, 1, function(u) {
   min(m[max(1,u[1]-1):min(nrow(m), u[1]+1), max(1,u[2]-1):min(ncol(m), u[2]+1)])
})

dim(x) = dim(m)

#> x
#     [,1] [,2] [,3] [,4]
#[1,]    1    1    3    3
#[2,]    1    1    2    2
#[3,]    2    2    1    1
#[4,]    3    3    1    1