TransWikia.com

How does gridmetrics handle IF condition in user defined functions?

Geographic Information Systems Asked by K_D on September 27, 2021

I noticed a kind of "inconsistency" in the values returned from two user-defined functions. I tested on a tile of 200mx200m to return a raster of pixel size 50m (16 pixels)

In the following function, if the condition is satisfied, the function returns ONLY one value.

funcky <- function(x)
{
  if (max(x) < 22)
     return(max(x))
}
grd <- grid_metrics(lasca, funcky(Z), 50)

When the condition is not satisfied, NA values are returned.

> as.array(grd[[1]])
, , 1

      [,1]  [,2]  [,3] [,4]
[1,] 19.92 21.90    NA   NA
[2,]    NA 21.46 21.89   NA
[3,]    NA 21.73    NA   NA
[4,]    NA    NA    NA   NA

I expected the same logic to be applied when the function returns a list of values. For example,

funcky <- function(x)
{
  if (max(x) < 22)
    return(list(max(x), mean(x), min(x)))
}
grd <- grid_metrics(lasca, funcky(Z), 50)

But the values are not NA, they are 0s as shown below.

> as.array(grd[[1]])
, , 1

      [,1]  [,2]  [,3] [,4]
[1,] 19.92 21.90  0.00    0
[2,]  0.00 21.46 21.89    0
[3,]  0.00 21.73  0.00    0
[4,]  0.00  0.00  0.00    0

, , 2

         [,1]     [,2]     [,3] [,4]
[1,] 6.555234 7.434102 0.000000    0
[2,] 0.000000 5.038366 5.733465    0
[3,] 0.000000 8.699386 0.000000    0
[4,] 0.000000 0.000000 0.000000    0

, , 3

      [,1]  [,2]  [,3] [,4]
[1,] -0.83 -0.04  0.00    0
[2,]  0.00 -0.07 -0.09    0
[3,]  0.00 -0.07  0.00    0
[4,]  0.00  0.00  0.00    0

If the metrics can have negative values (skewness, for example), then these 0s could potentially be misleading, as is the case in the third layer. Is this behaviour alright?

Adding an else {return(NULL)} didn’t make any difference. And adding else {return(list(NA,NA,NA))} generated an error:

Error: Column 1 of result for group 2 is type 'logical' but expecting type 'double'. Column types must be consistent for each group.

One Answer

Your example works even if it is not safe because funky returns NULL implicitly. The inconsistent behavior with 0s instead of NAs is a bug fixed in version 3.0.2 and probably introduced in v3.0.0 20 days before 3.0.2. Update lidR and it should work.

That being said it is not a good practice. It works because R is very permissive and allows bad coding practice. Adding an else statement was correct but grid_metrics uses data.table under the hood and is thus designed to be type safe. You cannot mix logical and numeric it won't be type casted automatically. In R NA is logical. So you were almost correct but using wrong types.

funcky <- function(x)
{
  if (max(x) < 22)
    return(list(max(x), mean(x), min(x)))
  else
    return(list(NA_real_, NA_real_, NA_real_)
}

Correct answer by JRR on September 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP