0

Currently, I am using United States Congressional District Shapefiles. I want to make a Cartogram using the steps laid out in the cartogram package. But I cannot seem to make it into the cartogram object using the cartogram_cont function successfully.

Any help, advice, or insight you can offer in getting me past this point and closer to the cartogram would be incredibly helpful.

Please the bottom of the code for where the error occurs.

Thank you!

######################### Library #####################
library(sf)
library(tmap)
library(cartogram)
library(ggplot2)
library(ggmap)
library(maptools)


###################### Get Congress Map ###################
get_congress_map <- function(cong=113) {
  tmp_file <- tempfile()
  tmp_dir  <- tempdir()
  zp <- sprintf("http://cdmaps.polisci.ucla.edu/shp/districts%03i.zip",cong)
  download.file(zp, tmp_file)
  unzip(zipfile = tmp_file, exdir = tmp_dir)
  fpath <- paste(tmp_dir, sprintf("districtShapes/districts%03i.shp",cong), sep = "/")
  st_read(fpath)
}


cd114 <- get_congress_map(114)

################ Create Congressional District ID ###################

State_Dictonary <- rbind(data.frame(state.abb, STATENAME= state.name), data.frame(state.abb= "DC", STATENAME= "District Of Columbia"))

#Add DC
cd114.1 <- merge(State_Dictonary, cd114, by = c("STATENAME"))
unique(cd114$STATENAME)
#**************** Paste Zero infront of Single Districts ****************
cd114.1$district_code <- as.character(cd114.1$DISTRICT)
cd114.1$district_code[cd114.1$district_code == 98] <- "01" #Account for the weird code for DC
cd114.1$district_code[cd114.1$district_code == 0] <- "01"  #Account for at large districts
cd114.1$district_code[cd114.1$district_code == 1] <- "01"
cd114.1$district_code[cd114.1$district_code == 2] <- "02"
cd114.1$district_code[cd114.1$district_code == 3] <- "03"
cd114.1$district_code[cd114.1$district_code == 4] <- "04"
cd114.1$district_code[cd114.1$district_code == 5] <- "05"
cd114.1$district_code[cd114.1$district_code == 6] <- "06"
cd114.1$district_code[cd114.1$district_code == 7] <- "07"
cd114.1$district_code[cd114.1$district_code == 8] <- "08"
cd114.1$district_code[cd114.1$district_code == 9] <- "09"

#************** Create CD in  Data ****************
cd114.1$CD <- paste(cd114.1$state.abb, cd114.1$district_code, sep = "")


################ Create Fake Data TO Simulate My Own ########################
CD <- unique(cd114.1$CD)
Values <- sample(1:100, 436, replace = T)

Df <- data.frame(CD, Values)


################### Merge Shape File to Donor #####################
#******************** Merge Descriptive Stats *********************
Df.2 <- merge(x = Df, y = cd114.1, by = c("CD"), all.y = T)

################### Make SF Object ####################
SF.DF.1 <- st_as_sf(Df.2)
SF.DF.2 <- st_make_valid(SF.DF.1)
class(SF.DF.2)

################### Make cartogram ####################
#Follow Proceedure Laid out: https://cran.r-project.org/web/packages/cartogram/readme/README.html

# I use st_transform instead of spTransform beause I'm using an SF Ojbect
SF.DF.3 <- st_transform(SF.DF.1, CRS("+init=epsg:3395")) 

cartogram_cont(SF.DF.3, "Value", itermax = 5)
#Error in Fij[distance <= radius[j]] <- Fbij[distance <= radius[j]] : 
#NAs are not allowed in subscripted assignments




Sharif Amlani
  • 1,138
  • 1
  • 11
  • 25

1 Answers1

2

The geometry entry in row 87 is empty (MULTIPOLYGON EMPTY). You can overcome this issue by:

library(dplyr)

SF.DF.3 <- st_transform(SF.DF.1, CRS("+init=epsg:3395")) %>% 
  filter(!st_is_empty(.))

Additionally, there's no column Value included in you df, it's Values ;)

sf_ncont <- cartogram_ncont(SF.DF.3, "Values")

tm_shape(sf_ncont) + tm_polygons("Values", style = "jenks", legend.show = FALSE) +
  tm_layout(frame = FALSE)

Note, I filtered out Alaska and Hawaii for the following plot, as well as used cartogram_ncont instead of cartogram_cont since the former operation is very time consuming.

enter image description here

mgrund
  • 1,415
  • 8
  • 10
  • 1
    Awesome! Thank you so much for your response! It is incredibly helpful. I really appreciate it. And thank you for catching the ```Value``` mistake as well. – Sharif Amlani May 28 '21 at 01:17
  • Also, why is there so much white space inside the map? The Continuous Area Cartogram tutorial listed in the package: https://cran.r-project.org/web/packages/cartogram/readme/README.html shows a filled-in map where the units are contiguous. Is there a way to mirror the tutorial? – Sharif Amlani Jun 02 '21 at 04:21