alarm-redist / redist

Simulation methods for legislative redistricting.
https://alarm-redist.github.io/redist/
GNU General Public License v2.0
67 stars 23 forks source link

Problem with add_edge and redist_map: Error message for false "Disconnected precincts" #153

Closed martial00120 closed 1 year ago

martial00120 commented 2 years ago

Hi!

I am trying to use redist for Cornwall and the Isles of Scilly in England (For debbung, I just use parts of Cornwall).

I have the following issues. If I just use the peninsular polygons, the code just runs fine. I can successfully add the islands, items c(1:4, 6) with add_edge to the peninsular (item 10, ferry port: "Penzance Promenade"). I get however errors with others polygon which are falsely considered "Disconnected precincts".

Error in redist_map(): ! Adjacency graph not contiguous. → Try manually editing the output of redist.adjacency(). ℹ Disconnected precincts: c(13, 14, 15, 16)

These precincts are not disconnected.

My questions:

Thanks and Best greetings from Switzerland Michael

My code is: library(redist) library(sf) library(geomander)

cornwall_sel <-st_read('cornwall_sel.shp')

geo_plot((cornwall_sel)) cornwall_adj <- redist.adjacency(cornwall_sel) cornwall_adj <- add_edge(cornwall_adj, c(1:4,5),rep(10,5)) cornwall_map = redist_map(cornwall_sel, total_pop = electorate, ndists=4, pop_tol=0.25, adj=cornwall_adj) grafik cornwall_sel.zip

CoryMcCartan commented 2 years ago

Hi Michael!

This is a weird one. Looks like there may be an issue with your shapefile. When I try to get the perimeter of each ward with st_length() I get all zeros. I think that's related to your problem.

In any event I was able to resolve it by switching to the geomander version of the adjacency-graph maker, which uses a different library. I also changed what looks like a typo in your code—ward 6, not 5, should be connected to the ferry port in Penzance, right?

Here's the code that worked for me.

library(redist)
library(sf)
library(geomander)

cornwall_sel <-st_read('~/Downloads/cornwall_sel/cornwall_sel.shp')

geo_plot(cornwall_sel)
cornwall_adj <- geomander::adjacency(cornwall_sel)
cornwall_adj <- add_edge(cornwall_adj, c(1:4, 6), rep(10, 5))
cornwall_map = redist_map(cornwall_sel, total_pop = electorate,
                          ndists=4, pop_tol=0.25, adj=cornwall_adj)

Some code you might find useful in debugging stuff like this:

library(ggplot2)
ggplot(cornwall_sel, aes(fill=factor(check_contiguity(cornwall_adj)$component))) + 
    geom_sf(size=0) + 
    guides(fill='none') +
    theme_void()

And sometimes the problem is a tiny gap between wards, which can be fixed with st_buffer().

Re: using names, this is hard because they don't always exist / there's no automatic way to associate them with row numbers. What I usually do is something like add_edge(shp, which(shp$name == "Name 1"), which(shp$name == "Name 1")) which is a little verbose but gets the job done.

Hope that helps!