r-spatialecology/landscapemetrics

sample_lsm() does not work on NA rasters

Closed this issue · 8 comments

The sample_lsm() function does not work when the sampled area is completely covered with NAs.

library(landscapemetrics)
library(raster)
#> Loading required package: sp

# prepare data ------------------------------------------------------------
r = raster(matrix(c(rep(NA, 18), 1:18), nrow = 6))

p = raster(matrix(c(rep(1, 18), rep(2, 18)), nrow = 6))
p_sp = rasterToPolygons(p, dissolve = TRUE)
#> Loading required namespace: rgeos

plot(r)
plot(p_sp, add = TRUE, lwd = 5)

# calculate metrics -------------------------------------------------------
my_metric = sample_lsm(r, p_sp, metric = "shdi")
#> Warning in seq_len(nrow(area_patch)): first element used of 'length.out'
#> argument
#> Error in seq_len(nrow(area_patch)): argument must be coercible to non-negative integer

The error probably starts here:

# calculate actual area of sample plot
area <- lsm_l_ta_calc(landscape_mask,
directions = 8)
# calculate lsm
result_current_plot <- calculate_lsm(landscape = landscape_mask,
verbose = verbose,
progress = FALSE,
...)

In my opinion, the proper result should return NA in the value column, and 0 in percentage_inside.

Smaller examples are attached below.
I think the functions should return value of NA in those cases. What do you think @mhesselbarth ?

library(raster)
library(landscapemetrics)

r = raster(matrix(rep(NA, 16), nrow = 4))
r
#> class      : RasterLayer 
#> dimensions : 4, 4, 16  (nrow, ncol, ncell)
#> resolution : 0.25, 0.25  (x, y)
#> extent     : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> crs        : NA 
#> source     : memory
#> names      : layer 
#> values     : NA, NA  (min, max)

# exhibit 1 ----------------------------------------------------------------
area <- landscapemetrics:::lsm_l_ta_calc(r,
                      directions = 8)
#> Warning in seq_len(nrow(area_patch)): first element used of 'length.out'
#> argument
#> Error in seq_len(nrow(area_patch)): argument must be coercible to non-negative integer


# exhibit 2 ---------------------------------------------------------------
result_current_plot <- calculate_lsm(landscape = r,
                                     verbose = verbose,
                                     progress = FALSE)
#> Error: All raster values NA.

Created on 2019-11-24 by the reprex package (v0.3.0)

Should be fixed: d35fe9d / 8530508

Hi @mhesselbarth - it works now! The only issue is the number of warnings... Would it be possible to cut it just to the two unique warnings?

library(landscapemetrics)
library(raster)
#> Loading required package: sp

r = raster(matrix(c(rep(NA, 18), 1:18), nrow = 6))

p = raster(matrix(1:36, nrow = 6))
p_sp = rasterToPolygons(p, dissolve = TRUE)
#> Loading required namespace: rgeos

plot(r)
plot(p_sp, add = TRUE, lwd = 5)

my_metric = sample_lsm(r, p_sp, metric = "shdi")
#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.

#> Warning: Please use check_landscape() to ensure the input data is valid.
#> Warning: Some of buffers extend over the landscape border. Consider decreasing
#> the size argument value.

Created on 2019-11-27 by the reprex package (v0.3.0)

The problem is that the warning(s) is/are thrown by calculate_lsm() which is executed for each sample plot. One possibility would be to move the check outside calculate_lsm() and set verbose = FALSE. This would return only one warning. However, this has the problem that also ALL other warnings in calculate_lsm() are not returned e.g. if less than 3 classes are present for IJI and so on.

I don't see any workaround at the moment that doesn't include any major structural changes, unfortunately.

Related to #130

Fixed with the help of @bitbacchus idea in #130: 7eb2aa8

Interestingly, it doesn't work with reprex(), but looks nice and neat on the local console for me.

Nice, it works perfectly :-)

🥇