I'm trying to automate my workflow, but having trouble with one step. My data come as processed shapefiles saved in .RDA files; I load them to a PostGIS system, cleaning up little issues (spTransform() to a local CRS, as.numeric() on a key field, etc).

When I simply load(c:/data/regionX-yearY.rda) they load as SpatialPolygonsDataFrame so I can simply regionX-yearY_3035 <- spTransform(regionX-yearY, "+init=epsg:3035") ... but for some reason looping over files from list.files() causes them to be loaded as characters, or their filehandle or something. The sf package errs with

"unable to find an inherited method for function ‘spTransform’ for signature ‘"character", "character"’"

Ideas as to what's going on here? Obviously I took some sort of implicit shortcut by hand.

  • The error is saying the first argument is a character value. The thing you have written as regionX-yearY is evaluating to a character value. Why? Load one in and print it out to check. Its not a SpatialPolygonsDataFrame. Of course looping over files with list.files creates characters, that's what list.files does. – Spacedman Sep 6 at 15:25
  • You're right @Spacedman, I get that list.files() returns characters -- but evidently I misunderstood how to loop through the resulting list to load() the files to manipulate them. I see a lot of examples of binding text/csv files to dataframes, though. – Jeff Sep 8 at 6:33

The problem here seems to be (and hard to be certain without more code or examples) that you have spatial data objects saved in multiple .RDA files and need to read them in a loop.

The struggle is because load loads things into, by default, the global environment under whatever name they were saved as, and load returns the name. Thinking that load returns the object itself and passing that to spatial functions will result in the functions being fed character strings instead of objects.

There's a couple of fixes, the neatest, I think, is to load the files into a new environment. Let's save x and remove it:

> x = 1:10 ; save(x,file="x.rda") ; rm(x)
> x
Error: object 'x' not found

If we load it back we magically get x back. The load itself returns invisibly:

> load("x.rda")
> x
 [1]  1  2  3  4  5  6  7  8  9 10

If we clean up and try again, but save the return from load, you'll see it is the name of the object loaded:

> rm(x)
> z = load("x.rda")
> z
[1] "x"
> x
 [1]  1  2  3  4  5  6  7  8  9 10

load can read to a different environment, so let's write a function that returns the object in a new environment:

> getRDA = function(f){e = new.env();load(f, env=e); return(e)}

so, starting without an x:

> rm(x)
Warning message:
In rm(x) : object 'x' not found

Use the function to read from x.rda - x is not created:

> e = getRDA("x.rda")
> x
Error: object 'x' not found

But you can get it from the returned e:

> e$x
 [1]  1  2  3  4  5  6  7  8  9 10

You can get the name of the thing loaded:

> names(e)
[1] "x"

which might be useful if you have coded information into the name, like "rainfall_1990_12".

If you don't care about the name or if it is encoded into the RDA filename then you can modify getRDA to return the object directly:

> getRDA = function(f){e = new.env();load(f, env=e); return(e[[names(e)]])}
> getRDA("x.rda")
 [1]  1  2  3  4  5  6  7  8  9 10

After I couldn't get @Spacedman's suggestion working I dropped it, feeling it was a bit out of hand; I later stumbled the simplest answer: I misunderstood load() and get().

After the file <- load(c:/data/regionX-yearY.rda) I had the filepath; this mislead me a bit as it's a ponderous load for these .rda files, actually "feels" like R has loaded something more than a char string, but class(file) confirms it's [1] "character". One needs to simply file <- get(file) to do operations on the sp or sf object itself: now class(file) says:

[1] "SpatialPolygonsDataFrame"
[1] "sp"

May my mea culpa prove useful to others.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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