2

I'm taking an R class and I have an assignment that I'm trying to figure out. Instructor wants us to save all layers in a gdb file as sf objects. He told us that we should use loops.

I'm able to import the gdb file using

scd <- st_read(dsn='/path/to.gdb')

And I'm also able to list layers using

scdl <- st_layers(dsn='/path/to.gdb')

Update:


 
 st_read(dsn = '/path/to.gdb', layer=i)
 feat <- st_read(code here)
}

i

this is what I have done so far which loops over the layernames. but when I try to assign them to objects using feat <- st_read(code here) line, it breaks my loop.

"Error in CPL_read_ogr(dsn, layer, query, as.character(options), quiet, : Expecting a single value: [extent=5]. In addition: Warning message: In if (nchar(dsn) < 1) { : the condition has length > 1 and only the first element will be used"

asked Sep 17, 2020 at 1:36
7
  • 1
    Have you been taught how to use the for function or any of the apply family of functions? Commented Sep 17, 2020 at 5:46
  • we have gone over apply family. I have some experience with loops from my previous Python studies. I'm trying to apply them here; scd <- st_read(dsn='/path/to.gdb') scdl <- st_layers(dsn='/path/to.gdb') for(i in scd) { st_as_sf(scd) save(scd, file="layer") st_write(i) ``` scdl gives me the names of every layer. but I need to save those layers as separate files which, I couldn't figure out. I assumed looping over scdl would work but it doesn't work. Commented Sep 17, 2020 at 6:08
  • 2
    Ok, edit that code into your question so its a bit neater, explain what happens when you run it (describe the output files and objects) and say how this is not what you want output or created. Commented Sep 17, 2020 at 7:34
  • 1
    File geodatabase isn't a file. It's a directory with many files that implement zero or more tables, some of which may contain geometry columns. Understanding that an FGDB is a container class is critical to using it correctly. Commented Sep 17, 2020 at 11:54
  • 1
    @Vince that's irrelevant - fgdb's present to GDAL as a collection of layers like any other GDAL vector driver source. Solution is to loop over the layer names, get the layers, save to some name (derived from the layer name, maybe, Q is unclear). Commented Sep 17, 2020 at 12:29

3 Answers 3

1

In the following code the sf objects are read and added to a list, which is a safe way of reading things in a for loop.

library(sf)
layer_list = st_layers("to.gdb")
layers_sf = list()
for(i in 1:length(layer_list$name)) {
 layers_sf[[layer_list$name[i]]] = read_sf(dsn = "to.gdb", layer = layer_list$name[i])
}
 # a plot f the first to test the list object `layers_sf`:
plot(layers_sf[[1]])
answered Sep 17, 2020 at 15:36
2
  • Thank you this is what I get; Error: unexpected ')' in: "for(i in 1:length(layer_list$name)) { layers_sf[[layer_list$name[i]]] = read_sf(dsn = 'pathtomygdb.gdb', layer = layer_list$name[i]))" > } Error: unexpected '}' in "}" Please see my updates on my question Commented Sep 17, 2020 at 15:53
  • I corrected the code, there was a parenthesis in excess, now it should work Commented Sep 17, 2020 at 15:59
1

I had my class and this is what I was able to come up with, which worked and got accepted;

scdl <- st_layers('path/to.gdb')
for(i in scdl$name) {
 
 feat <- st_read(dsn = 'path/to.gdb', layer=i)
 plot(feat)
}

My professor said function lapply would have been the best solution but this works as well. Thank you for all the help and suggestions, much appreciated!

answered Sep 20, 2020 at 17:10
0

Replace the for-loop with the purrr package.

st_layers will list all of the names within your gdb and then purrr::map uses the list of names with st_read to read each vector into R from your gdb.

library(sf)
path<-"path/to/your.gdb"
gdb<-st_layers(path)
list_of_features<-purrr::map(gdb$name,~st_read(dsn=path,layer=.))
answered Mar 22, 2022 at 16:16

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.