Skip to main content
4 of 4
refined code
Jeffrey Evans
  • 32k
  • 2
  • 48
  • 97

Now that we have indicated all of the issues you could try some clustering approaches using optimizations such as Simulated Annealing. Here is a quick worked example using Max-p Simulated Annealing. The use of queen_weights is defining first order neighbors (those that touch) and the optimization target is 10% of the population which would be similar to your "sum to 1 target". Keep in mind that this clustering approach uses simulated annealing so, changes in the heating parameter can result in very different solutions.

library(sf)
library(rgeoda)

guerry <- st_read(system.file("extdata", "Guerry.shp", 
                  package = "rgeoda"))
  guerry <- guerry[c('Crm_prs','Crm_prp','Pop1831')]

ijw <- queen_weights(guerry)
  mpc <- maxp_sa(ijw, guerry, guerry['Pop1831'], 3236.67, 
                 cooling_rate=0.85, sa_maxit=1)
    guerry$clust <- mpc$Clusters
      plot(guerry["clust"])

Here we check the solution(s)

for(i in sort(unique(guerry$clust))) {
  cat("sum of cluster", i, sum(guerry[guerry$clust == i,]$Pop1831),
      "with target of 3236.67",  "\n")
}   

example cluster solution

Now, lets look at your data (p sf polygon object was created from the structure output in the original post).

ijw <- queen_weights(p)
  mpc <- maxp_sa(ijw, p, p["lprd_offtk"], 1, 
                 cooling_rate=0.85, sa_maxit=1)
    p$clust <- mpc$Clusters
      plot(p["clust"])

Here we can check how close to target sum we get (in my run it was 2 cluster solutions with 1.261058 and 1.047192).

for(i in sort(unique(p$clust))) {
  cat("sum of cluster", i, sum(p[p$clust == i,]$lprd_offtk),
      "with target of 1",  "\n")
}

your data cluster solution

Jeffrey Evans
  • 32k
  • 2
  • 48
  • 97