how to make a data frame into a simple features data frame?
UPDATE
The answer from @Franz Plumpton is the correct correct solution with a single epsg. My answer below is only necessary when each row of a data.frame has a different epsg. Otherwise, this would be a duplicate (as pointed out by @Henrik above).
library(sf)
library(tibble)
df <- data_frame(place = c("London", "Kalamazoo"),
lat = c(51.5074, 396088), lon = c(0.1278, 5452158),
epsg = c(4326, 32610))
l <- lapply(unique(df$place), function(x){
df <- df[df$place == x,]
epsg <- df$epsg[1]
df <- st_as_sf(df, coords = c('lon', 'lat'), crs = epsg)
})
you could then transform all to the same epsg and combine into a single data.frame:
do.call(rbind, lapply(l, function(x) x <- st_transform(x, 4326)))
Convert from simple feature geometry to dataframe
You already have a data.frame, and you can perform transformations on the st_sfc objects in it,
using basic affine transformations. For example
df1[1,1] = df1[1,1] + c(2,0)
ggplot(df1) +
geom_sf(aes(geometry = geometry))
Explanatory note: df1[1,1]
selects the first column and row, which is the star. Adding c(2,0)
translates it by +2 in the x direction.
The answer to the question you actually asked:
If you really need the x,y cordinates as columns in a data.frame, you can use
df2 = data.frame(st_coordinates(df1[,1]))
However, for the use case you described, the first method above will be better. Not just because it is faster and neater, but because manipulating the sf objects themselves will take care of things like crs and extent.
How to convert list of -sf dataframes into single dataframe with geometry per row in R?
You need to make sure your sf
objects have the same crs, otherwise you cannot combine their geometries into a single sfc
(simple feature column). Once we transform them into longlat
for example, we can just rbind
them.
df_ll = map(df, ~ st_transform(., 4326))
df_sf = do.call(rbind, df_ll)
## or using Reduce
df_sf = Reduce(rbind, df_ll)
## or using purrr version of reduce
df_sf = reduce(df_ll, rbind)
Convert data frame containing coordinates of polygons to sf
I always struggle with doing this sf
transformation too, because it's not straight forward.
The first step (and hard part) is to build a st_object
(here st_polygon
) for each individual geometry represented.
To do that, convert each existing list
into a matrix
. Once each polygon representation is a n-row matrix
(one row for each point) we convert the matrix to a one element list
to feed into st_polygon()
. Now dat$geometry
is a list appropriately classed of POLYGONS
.
library(tidyverse)
dat %>%
mutate(geometry = map(geometry,
~ do.call(rbind, .) %>% # make each list a matrix
list() %>% # st_polygon() requires a list
st_polygon()
)
) %>%
st_as_sf()
Then the final step is to call st_as_sf()
on the entire data frame. It will auto-detect the now properly formatted geometry
column and produce a nice new sf
object for you. Happy mapping!
EDIT: If you want to build polygons with holes, the process is similar. st_polygon()
will process a multi-element list as if the the first element is the polygon and the remaining elements are holes in the first. It does require that you use map
twice, because you still need to build a matrix out of each list element, but need keep the lists of grouped matrixs together for processing the holes.
dat2 <- tibble::tribble( ~code, ~geometry, "MIE", list(list(c(1.24, 45), c(1.25, 45), c(1.25, 46), c(1.24, 45)), list(c(1.245,45.5), c(1.246,45.7), c(1.245,45.5))) )
dat %>%
mutate(geometry = map(dat$geometry,
~ map(.,
~ do.call(rbind, .) # make each list a matrix
) %>%
st_polygon()
)
) %>%
st_as_sf()
Convert sf object to dataframe and restore it to original state
I think geom
isn't in a format st_geometry
is expecting. st_as_text
converted your geometry into WKT as discussed in the help:
The returned WKT representation of simple feature geometry conforms to the simple features access specification and extensions, known as EWKT, supported by PostGIS and other simple features implementations for addition of SRID to a WKT string.
https://r-spatial.github.io/sf/reference/st_as_text.html
Instead, use st_as_sf(wkt=)
to set the new (old) geometry.
st_as_sf(geo_df, wkt = "geom", crs = 4326)
Create sf object from two-column matrix
As per the sf docs
m %>%
as.data.frame %>%
sf::st_as_sf(coords = c(1,2))
Creating sf polygons from a dataframe
I figured out an answer based on paqmo's suggestion to look at Convert sequence of longitude and latitude to polygon via sf in R
The answer provided in that question groups all the points in the data frame as a single polygon. I've added a step to group the dataframe by the variable that identifies the polygon.
polygon <- my.df %>%
st_as_sf(coords = c("Easting", "Northing"), crs = utm18) %>%
group_by(Plot) %>%
summarise(geometry = st_combine(geometry)) %>%
st_cast("POLYGON")
Create a sfc_GEOMETRY object from a data frame of vectors in R
Each element of the geometry
column is simply a two-column matrix wrapped in a list in another list. You can therefore just edit them directly...
States$geometry[n][[1]][[1]] <- as.matrix(exCoords)
where n
is the row number of States
that you want to replace. All of the sfc_geometry attributes are retained.
R create sf polyline from nested list of coordinates
Your feature
looks like the result of converting geojson
into an R object
If you have access to the geojson object before it is converted into your feature
, then you can ignore the to_json()
step(s) here
library(sf)
## convert back to JSON
### Option 1
js <- jsonify::to_json(feature, unbox = TRUE)
### Option 2
js <- jsonlite::toJSON(feature, auto_unbox = TRUE)
## Then you can convert to SF
### Option 1
geojsonsf::geojson_sf(js)
### Option 2
sf::st_read(js)
Related Topics
How to Reorder Factor Levels in a Tidy Way
Converting R Matrix into Latex Matrix in the Math or Equation Environment
Extract Column Name in Mutate_If Call
Export All User Inputs in a Shiny App to File and Load Them Later
Set Environment Variables for System() in R
Faster Way to Compare Rows in a Data Frame
Understanding Dates/Times (Posixc and Posixct) in R
What Does Passing an Ellipsis (...) as an Argument Mean in R
What Are Helpful Optimizations in R for Big Data Sets
Xpath to Extract Text After Br Tags in R
What Are Productive Ways to Debug Rcpp Compiled Code Loaded in R (On Os X Mavericks)
R Pheatmap: Change Annotation Colors and Prevent Graphics Window from Popping Up
How to Convert by the Minute Data to Hourly Average Data
How to Make an Overlapping Barplot
Can't Connect to Local MySQL Server Through Socket Error When Using Ssh Tunel