Can lidR opt_filter() Use Conditional Terms?
When working with massive LiDAR datasets in R, the lidR package is the industry standard for processing efficiency. A common question arises: "Can I use complex logical conditions inside opt_filter() like I do in filter_poi()?" The short answer is yes, but the syntax is different. While filter_poi() uses R-style logical expressions on data already loaded into memory, opt_filter() passes commands directly to the underlying LASlib reader. This allows you to discard points before they ever reach your RAM, providing a massive speed boost for LAScatalog workflows.
Table of Content
- Purpose of Pre-Reading Filters
- Common Use Cases
- Step by Step: Implementing Conditional Filters
- Best Results for Memory Optimization
- FAQ
- Disclaimer
Purpose
The primary purpose of opt_filter() is Streamlined Data Ingestion. By applying filters at the file-reading stage, the LAScatalog engine prevents superfluous points from being processed in your R environment. This is critical when your analysis only requires a specific subset of data—such as only ground points or first returns—over a study area spanning hundreds of square kilometers. Unlike filter_poi(), which filters data after it occupies memory, opt_filter() ensures your R session remains lightweight and responsive.
Use Case
Use conditional opt_filter() logic when:
- Memory Constraints: Your dataset is too large to load even in chunks without pre-filtering.
- Class-Specific Analysis: You only want to generate a DTM (Digital Elevation Model) and only need
Classification == 2. - Height Thresholding: You need to ignore "noise" points that are physically impossible (e.g., Z < -50 or Z > 500).
- Return Throttling: You only want to calculate metrics for
First Returnsto speed up canopy cover estimations.
Step by Step
1. Understand the LASlib Syntax
Since opt_filter() uses LASlib syntax, you must use specific flags (starting with -) rather than standard R operators. To see a full list of available filters, you can run:
readLAS(filter = "-help")
2. Apply Basic Logical Filters
To filter a LAScatalog for specific classifications (e.g., Ground and Water), use the -keep_class flag:
opt_filter(ctg) <- "-keep_class 2 9"
3. Use Conditional Range Terms
If you need to filter based on height (Z) or other numerical attributes, use the drop or keep range flags:
opt_filter(ctg) <- "-drop_z_below 0 -drop_z_above 150"
4. Combine Multiple Conditions
You can "chain" these flags together to create complex conditional subsets. For example, to keep only ground points that have an intensity greater than 50:
opt_filter(ctg) <- "-keep_class 2 -keep_intensity_above 50"
5. Process the Catalog
Once the option is set, any function applied to the catalog (like pixel_metrics or rasterize_terrain) will automatically respect these filters:
dtm <- rasterize_terrain(ctg, res = 1, algorithm = tin())
Best Results
| Requirement | Recommended Flag | Performance Impact |
|---|---|---|
| Ground Only | -keep_class 2 |
Very High (Reduces data by ~80%) |
| First Returns | -keep_first |
High |
| Remove Overlap | -drop_overlap |
Moderate |
| Z-Range Filter | -keep_z_range 0 50 |
High (Removes air/subsurface noise) |
FAQ
Can I use 'OR' logic in opt_filter?
LASlib logic is generally additive (AND). To perform an "OR" operation (e.g., Class 2 OR Class 9), you simply list both values in a single flag like -keep_class 2 9. For more complex logic that LASlib can't handle, you may still need to use filter_poi() inside your custom mapping functions.
Does opt_filter() work with LAZ files?
Yes. lidR handles the decompression on-the-fly, and the filters are applied as the points are decompressed, maintaining high efficiency.
Why isn't my filter working?
Ensure there are no extra spaces inside the quotes and that you are using the correct flag names. Common mistakes include using = instead of a space (e.g., use -keep_class 2, not -keep_class=2).
Disclaimer
Using opt_filter() permanently excludes points from the computation for that specific run. If you filter out ground points but try to run a terrain normalization, the result will be invalid. This guide is based on lidR version 4.x and above (as of 2026). Always check your point cloud classification accuracy before relying solely on class-based filters.
Tags: lidR, LiDAR, Rstats, SpatialData
