This is an update to this previous blog post.
Ever since the announcement of rgdal retiring, I’ve been meaning to update the process of transforming or re-projecting your coordinates. If you haven’t heard about it, this blog post from r-spatial covers the announcement and plans moving forward.
As I’ve mentioned previously, unless there’s a need to use older spatial libraries in R, you should be using sf. Unfortunately for most of us in the ecological communities, a lot of geospatial ecology libraries are still dependent on sp. Fortunately, there is a function in sf that allows us to work with sp, which I will cover at the end of this blog post.
First, lets import sf and load some data. For the purposes of this blog, I’m just going to use the coordinates of Santa Cruz that I had used previously in this post. Please note that since Santa Cruz and Oxford are several UTM zones away from each other, I will only use Santa Cruz’s coordinates.
library(sf) library(dplyr) df <- data.frame(city = c("Santa Cruz"), lat = c(36.974117), long = c(-122.030792)) df_sf <- st_as_sf(x = df, coords = c("long", "lat"), crs = 4326)
Now lets go over what I just did. I called the necessary libraries to get us started. sf is the simple features library and the successor to sp. dplyr is part of the tidyverse, the primary data science library in R. The function st_as_sf converts an object into a simple features object. If you’re unfamiliar with simple features, I highly recommend you read the documentation on github. So we basically took a dataframe, then converted it into a simple features object with the crs 4326, or the unprojected latitude longitude points.
Now, we want to transform those coordinates into the appropriate UTM. I already know that Santa Cruz, CA is in UTM 10N. Its epsg is 32610 for WGS84. Make sure you know your datum. The epsg for UTM 10N in NAD83 is 26910. Don’t freak out too much though if you goof it up. The difference is only a meter or so. General speaking, if you’re using a GPS unit, the datum is WGS84.
To transform the coordinates, we will use the function st_transform.
df_utm <-st_transform(df_sf, crs = 32610)
To confirm that the coordinates are in the correct project, we can confirm using the function st_crs.
Which gives us this output which confirms the transformation was successful.
> st_crs(df_utm) Coordinate Reference System: User input: EPSG:32610 wkt: PROJCRS["WGS 84 / UTM zone 10N", BASEGEOGCRS["WGS 84", DATUM["World Geodetic System 1984", ELLIPSOID["WGS 84",6378137,298.257223563, LENGTHUNIT["metre",1]]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]], ID["EPSG",4326]], CONVERSION["UTM zone 10N", METHOD["Transverse Mercator", ID["EPSG",9807]], PARAMETER["Latitude of natural origin",0, ANGLEUNIT["degree",0.0174532925199433], ID["EPSG",8801]], PARAMETER["Longitude of natural origin",-123, ANGLEUNIT["degree",0.0174532925199433], ID["EPSG",8802]], PARAMETER["Scale factor at natural origin",0.9996, SCALEUNIT["unity",1], ID["EPSG",8805]], PARAMETER["False easting",500000, LENGTHUNIT["metre",1], ID["EPSG",8806]], PARAMETER["False northing",0, LENGTHUNIT["metre",1], ID["EPSG",8807]]], CS[Cartesian,2], AXIS["(E)",east, ORDER, LENGTHUNIT["metre",1]], AXIS["(N)",north, ORDER, LENGTHUNIT["metre",1]], USAGE[ SCOPE["unknown"], AREA["World - N hemisphere - 126Â°W to 120Â°W - by country"], BBOX[0,-126,84,-120]], ID["EPSG",32610]]
Now what if we want the dataframe as an sp dataframe, which is necessary for oh so many ecology libraries? We use the funtion as_Spatial. We’re going to be a little bit explicit and make sure we call it from sf though.
df_sp <- sf::as_Spatial(df_utm)
And that’s it. If you made it this far, all the code is:
library(sf) library(dplyr) df <- data.frame(city = c("Santa Cruz"), lat = c(36.974117), long = c(-122.030792)) df_sf <- st_as_sf(x = df, coords = c("long", "lat"), crs = 4326) df_utm <-st_transform(df_sf, crs = 32610) st_crs(df_utm) df_sp <- sf::as_Spatial(df_utm)