5

I am trying to use data from the maps package in an sf workflow. I'm not sure if I have the operation correct (see below). It seems to work until state 20 (massachusetts). What am I doing wrong? Maybe there is a better way to do this?

state_data <- ggplot2::map_data("state")
state_data_sf <- lapply(unique(state_data$region),
                function(x)
                  list(matrix(unlist(
                  state_data[state_data$region == x,][,c("long", "lat")]),
                  ncol = 2)))

sf::st_polygon(state_data_sf[[19]])

POLYGON((-87.4620056152344 30.3896808624268, -87.4849319458008 39.6200332641602, -78.1113357543945 39.6658706665039, -78.1342544555664 39.67732...

sf::st_polygon(state_data_sf[[20]])

Error in MtrxSet(x, dim, type = "POLYGON", needClosed = TRUE) : polygons not (all) closed

juturna
  • 1,203
  • 7
  • 19
jsta
  • 1,345
  • 1
  • 13
  • 30

1 Answers1

10

I figured it out. The polygons need to be manually closed by rbinding the first row:

state_data <- ggplot2::map_data("state")
state_data_sf <- lapply(unique(state_data$region),
                function(x)
                  list(matrix(unlist(
                  rbind(
                    state_data[state_data$region == x,][,c("long", "lat")],
                    state_data[state_data$region == x,][1, c("long", "lat")])),
                  ncol = 2)))
res <- lapply(state_data_sf, sf::st_polygon)

EDIT

This is a much better solution. It is cleaner and does not suffer from closed polygon issues.

states <- sf::st_as_sf(maps::map("state", plot = FALSE, fill = TRUE))
jsta
  • 1,345
  • 1
  • 13
  • 30
  • Used this resource to answer: https://eriqande.github.io/rep-res-web/lectures/making-maps-with-R.html – jsta Mar 02 '17 at 21:27
  • st_as_sf works well. I'm wondering, however, why is fill=TRUE necessary? – husB Mar 26 '23 at 09:09