0

I am trying to produce a script which has functions that can produce a list of statistics and writes them to data.frame, which can in turn be written to a csv file if needed. This would be to check that individual .las files in a directory meet contractual obligations and produce 'reports' on them (so to speak).

I have read in the data as a LAScatalog and am trying to access the classification information. I have tried to follow the advice given in Lasinfo like task with lascatalog lidR and tried to read in the individual files (see below):

las_directory <- 'path/to/las/directory' # las_catalog <- readLAScatalog() already exists in the code using this path
las_catagories <- lapply(las_directory, function(las_directory) {
las <- readLAS(las_directory, select = "c")
table(las$Classification)})

This is for use within a function with a similar structure to the example in the 'Make a high level function' section in this vignette https://cran.r-project.org/web/packages/lidR/vignettes/lidR-LAScatalog-engine.html#making-a-valid-function-for-catalog_apply

It produced this error:

Error in as.list.default(X) : no method for coercing this S4 class to a vector

I tried to change the function to the following to see if it made any difference:

las_catagories <- lapply(las_directory, function(las) {
las <- readLAS(las_directory, select = "c")
table(las$Classification)})

and it produced the following error:

Error in streamLAS.character(files, ofile = "", select, filter) : File(s) are not las or laz

I subsequently tried to test it on a single file:

las_file <- paste0(las_directory, "7935.las")
las <- readLAS(las_file, select = "c")
table(las$Classification)})

which worked and produce the following:

>las_catagories
[[1]]
      1        2        3        4        5        7       19
1469047 26217559  2076049    34974     6353   255433 13398340

I then retried with the las_directory after ensuring it contained the right file path and it produced the error Error: File does not exist. I used las_list <- list.file(las_directory) and it produced the following error again:

Error in streamLAS.character(files, ofile = "", select, filter) : File(s) are not las or laz

I then tried to define the function separately:

select_classifications <- function(las){
las <- readLAS(las, select = 'c')
table(las$Classifications)
}

and use a for loop to apply it to the las_directory:

for (las in las_directory) {
select_classifications(las)
}

which returned the same as the previous error (file(s) are not las or laz so I then tested it on a a single las_file again, and again it worked fine. I then tried lapply again:

for (las in las_directory {
lapply(select_classifications(las))
}

and it produced the following error:

Error in lapply(select_classifications(las)):
argument "FUN" is missing, with no default

Finally I tried to iterate through the directory using the following code:

las_files <- list.files('path/to/directory')
for (file_name in las_files) {
data_list[[file_name]] <- readLAS(file_name)

which produced the error Error: File does not exist

Sorry for the long question, but I wanted to show all my attempts either for someone to point out how ridiculous they are, or to ensure that everyone's time is saved. Just to note, there is over 4000 .las files, all around 1gb in size. I am using future::plan(multisession, workers = 8) to process this. It means automation is key rather than having to go through them all by hand! I have also tried using whitebox tools, but currently there are restrictions on new R packages from our IT department (for reasons...) and it is waiting in the ticket queue to be given permission.

1 Answer 1

2

Sounds like you misunderstand how to loop through files of a folder in R. Nothing related to lidR. You have several options.

you can loop

las_files <- list.files('path/to/directory', full.names = T)
for (file_name in las_files) {
las <- readLAS(file_name)
do_smothing(las)
}

you can apply (which is like a loop)

las_files <- list.files('path/to/directory', full.names = T)
lapply(las_files, function(x) {
las <- readLAS(x)
do_something(las)
})

You can use the lidR engine

do_something = function(chunk)
{
  las = readLAS(chunk)
  if (is.empty(las) return(NULL)
  # do something
}

ctg = readLAScatalog("path/to/directory", chunk_buffer = 0)
catalog_apply(ctg, do_something)
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.