# How does gridmetrics handle IF condition in user defined functions?

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 `0`s 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 `0`s 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.
``````

Your example works even if it is not safe because `funky` returns `NULL` implicitly. The inconsistent behavior with `0`s instead of `NA`s 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_)
}
``````
• Yes, updating to 3.0.2 worked. I wasn't aware of the data type NA_real_. Thanks for that! While improving some code, I have come across some 'best practices' for `if-else` and was curious about how `grid-metrics` handled it. I suppose it is a useful clarification.
– K_D
Commented Jul 28, 2020 at 12:52
• This is not actually about best practices for `if-else` but about undefined behavior in functions. No matter the path taken in the code, a function should always explicitly return something. In your case `funcky` has an undefined behavior for `x >= 22`. Hopefully R handle such case natively with `NULL` and the behavior of `grid_metrics` is made in such a way that it works. But you should avoid undefined behaviors.
– JRR
Commented Jul 28, 2020 at 13:36