2.2 Simple feature geometry, simple feature geometry list-column, and simple feature

Here, we learn how different types of sfg are constructed. We also learn how to create sfc and sf from sfg from scratch.34

2.2.1 Simple feature geometry (sfg)

The sf package uses a class of sfg (simple feature geometry) objects to represent a geometry of a single geometric feature (say, a city as a point, a river as a line, county and school district as polygons). There are different types of sfgs. Here are some example feature types that we commonly encounter as an economist35:

  • POINT: area-less feature that represents a point (e.g., well, city, farmland)
  • LINESTRING: (e.g., a tributary of a river)
  • MULTILINESTRING: (e.g., river with more than one tributary)
  • POLYGON: geometry with a positive area (e.g., county, state, country)
  • MULTIPOLYGON: collection of polygons to represent a single object (e.g., countries with islands: U.S., Japan)

POINT is the simplest geometry type and is represented by a vector of two36 numeric values. An example below shows how a POINT feature can be made from scratch:

#--- create a POINT ---#
a_point <- st_point(c(2, 1))

The st_point() function creates a POINT object when supplied with a vector of two numeric values. If you check the class of the newly created object,

#--- check the class of the object ---#
class(a_point)
[1] "XY"    "POINT" "sfg"  

you can see that it’s indeed a POINT object. But, it’s also an sfg object. So, a_point is an sfg object of type POINT.


A LINESTRING objects are represented by a sequence of points:

#--- collection of points in a matrix form ---#
s1 <- rbind(c(2, 3), c(3, 4), c(3, 5), c(1, 5))

#--- see what s1 looks like ---#
s1
     [,1] [,2]
[1,]    2    3
[2,]    3    4
[3,]    3    5
[4,]    1    5
#--- create a "LINESTRING" ---#
a_linestring <- st_linestring(s1)

#--- check the class ---#
class(a_linestring)
[1] "XY"         "LINESTRING" "sfg"       

s1 is a matrix where each row represents a point. By applying st_linestring() function to s1, you create a LINESTRING object. Let’s see what the line looks like.

plot(a_linestring)

As you can see, each pair of consecutive points in the matrix are connected by a straight line to form a line.


A POLYGON is very similar to LINESTRING in the manner it is represented.

#--- collection of points in a matrix form ---#
p1 <- rbind(c(0, 0), c(3, 0), c(3, 2), c(2, 5), c(1, 3), c(0, 0))

#--- see what s1 looks like ---#
p1
     [,1] [,2]
[1,]    0    0
[2,]    3    0
[3,]    3    2
[4,]    2    5
[5,]    1    3
[6,]    0    0
#--- create a "POLYGON" ---#
a_polygon <- st_polygon(list(p1))

#--- check the class ---#
class(a_polygon)
[1] "XY"      "POLYGON" "sfg"    
#--- see what it looks like ---#
plot(a_polygon)

Just like the LINESTRING object we created earlier, a POLYGON is represented by a collection of points. The biggest difference between them is that we need to have some positive area enclosed by lines connecting the points. To do that, you have the the same point for the first and last points to close the loop: here, it’s c(0,0). A POLYGON can have holes in it. The first matrix of a list becomes the exterior ring, and all the subsequent matrices will be holes within the exterior ring.

#--- a hole within p1 ---#
p2 <- rbind(c(1, 1), c(1, 2), c(2, 2), c(1, 1))

#--- create a polygon with hole ---#
a_plygon_with_a_hole <- st_polygon(list(p1, p2))

#--- see what it looks like ---#
plot(a_plygon_with_a_hole)


You can create a MULTIPOLYGON object in a similar manner. The only difference is that you supply a list of lists of matrices, with each inner list representing a polygon. An example below:

#--- second polygon ---#
p3 <- rbind(c(4, 0), c(5, 0), c(5, 3), c(4, 2), c(4, 0))

#--- create a multipolygon ---#
a_multipolygon <- st_multipolygon(list(list(p1, p2), list(p3)))

#--- see what it looks like ---#
plot(a_multipolygon)

Each of list(p1,p2) and list(p3) represents a polygon. You supply a list of these lists to the st_multipolygon() function to make a MULTIPOLYGON object.

2.2.2 Create simple feature geometry list-column (sfc) and simple feature (sf) from scratch

To make a simple feature geometry list-column (sfc), you can simply supply a list of sfg to the st_sfc() function as follows:

#--- create an sfc ---#
sfc_ex <- st_sfc(list(a_point, a_linestring, a_polygon, a_multipolygon))

To create an sf object, you first add an sfc as a column to a data.frame.

#--- create a data.frame ---#
df_ex <- data.frame(name = c("A", "B", "C", "D"))

#--- add the sfc as a column ---#
df_ex$geometry <- sfc_ex

#--- take a look ---#
df_ex
  name                       geometry
1    A                    POINT (2 1)
2    B LINESTRING (2 3, 3 4, 3 5, ...
3    C POLYGON ((0 0, 3 0, 3 2, 2 ...
4    D MULTIPOLYGON (((0 0, 3 0, 3...

At this point, it is not yet recognized as an sf by R yet.

#--- see what it looks like (this is not an sf object yet) ---#
class(df_ex)
[1] "data.frame"

You can register it as an sf object using st_as_sf().

#--- let R recognize the data frame as sf ---#
sf_ex <- st_as_sf(df_ex)

#--- see what it looks like ---#
sf_ex
Simple feature collection with 4 features and 1 field
Geometry type: GEOMETRY
Dimension:     XY
Bounding box:  xmin: 0 ymin: 0 xmax: 5 ymax: 5
CRS:           NA
  name                       geometry
1    A                    POINT (2 1)
2    B LINESTRING (2 3, 3 4, 3 5, ...
3    C POLYGON ((0 0, 3 0, 3 2, 2 ...
4    D MULTIPOLYGON (((0 0, 3 0, 3...

As you can see sf_ex is now recognized also as an sf object.

#--- check the class ---#
class(sf_ex)
[1] "sf"         "data.frame"

  1. Creating spatial objects from scratch yourself is an unnecessary skill for many of us as economists. But, it is still good to know the underlying structure of the data. Also, occasionally the need arises. For example, I had to construct spatial objects from scratch when I designed on-farm randomized nitrogen trials. In such cases, it is of course necessary to understand how different types of sfg are constructed, create sfc from a collection of sfgs, and then create an sf from an sfc.↩︎

  2. You will hardly see the other geometry types: MULTIPOINT and GEOMETRYCOLLECTION. You may see GEOMETRYCOLLECTION after intersecting two spatial objects. You can see here if you are interested in learning what they are.↩︎

  3. or three to represent a point in the three-dimensional space↩︎