0

I've used the focalWeight function in R's raster package to create focal "moving window" weight matrices for tens of thousands of images. On a few dozen of the images the function does not behave as expected. I expect a 3x3 matrix, but am returned a 1x3 matrix.

Upon digging into the problem I think it is due to the floor function which is called internally.

I'll demonstrate the problem below (I have a raster named r). I'm running code from .circular.weight

res(r)                               # raster resolution is 1
#[1] 1 1
rs <- res(r)
d <- 1                               # window diameter is 1
nx <- 1 + 2 * floor(d/rs[1])         # number of columns is 3
nx                                   #  this is expected
#[1] 3                                  
ny <- 1 + 2 * floor(d/rs[2])          # number of rows is 1
ny                                    # this is unexpected
#[1] 1
1 + 2 * floor(d/rs[2])
#[1] 1
2 * floor(d/rs[2])
#[1] 0
floor(d/rs[2])                         # the floor of 1 is 0
#[1] 0
d/rs[2]
#[1] 1
floor(1)                            # but the floor of 1 should be 1
#[1] 1

res(r) == 1                        # the resolution appears to be 1, 1
# [1] 1 1
res(r) == 1                        # but it isn't really
# [1]  TRUE FALSE

?floor says that unexpected results like this have been seen before. It says, "It is normally necessary to use a tolerance."

How do I use a tolerance? How can I fix the focalWeight function?

Tedward
  • 1,652
  • 15
  • 19
  • I used `r <- raster(ncol=2, nrow=1)` then `res(r)<-c(1,1)` to set the same one row, two column matrix with 1,1 in it and then ran your code and got 3 for both nx & ny....not sure why it fails for you. It could be that you have a library loaded which is blocking floor, or has reassigned it with a different calculation. – sconfluentus Jul 06 '17 at 00:00
  • I'm calling this function on 9800 images. It works for all but a few dozen of the images. Therefore the problem must lie with the images themselves. The resolution isn't exactly 1 and 1 for these images that cause it to fail. I think I'd have to send you the image to have you actually reproduce the problem. – Tedward Jul 06 '17 at 00:26

1 Answers1

0

By using round, I can solve the problem. This answer told me how to work with unexpected results of floor

> floor(d/rs[2])
[1] 0
> floor(d/round(rs[2]))
[1] 1

This works in my case where the resolution is 1 1. I'm not sure about other cases.

Tedward
  • 1,652
  • 15
  • 19
  • Did the equation actually fail you prior to using round? I tested it and it worked fine.... – sconfluentus Jul 06 '17 at 00:01
  • the function worked, but it produced a 1x3 matrix instead of a 3x3 matrix. This caused the focal function, which I called next, to throw an error. – Tedward Jul 06 '17 at 00:23
  • I just had to create simulated data, so there is a very good chance that it is something hidden in a file and likely not the function, but a format that needs adjusting in some way before passing the image in – sconfluentus Jul 06 '17 at 00:42