Programmering

Sådan oprettes et valgkort i R

Hvis du kortlægger valgresultater for f.eks. Det amerikanske præsidentvalg efter stat, kan det være fornuftigt at bare vise en rød farve for stater, der er vundet af republikanere, og en farve blå for stater, der er vundet af demokrater. Det er fordi det ikke betyder noget, om en kandidat vinder med tre tusinde stemmer eller tre millioner: Det er "vinder tager alt."

Men når man analyserer resultaterne af en statsvalg ved amt, eller a valg i hele byen ved område, margenen betyder noget. Det er den samlede sum, der bestemmer vinderen. At vinde "Atlanta" i sig selv er ikke alt, hvad du behøver at vide, når du f.eks. Ser på statslige resultater fra Georgien for guvernør. Du vil gerne vide, hvor mange stemmer demokraten vandt ved, og sammenlign det med andre områder.

Derfor kan jeg godt lide at oprette kort, der er farvekodet af vinderen og med farveintensitet, der viser sejrsmargen. Det fortæller dig, hvilke områder der bidrog mere, og hvilke der bidrog mindre til det samlede resultat.

I denne demo bruger jeg præsidentresultaterne i Pennsylvania 2016. Hvis du gerne vil følge med, skal du downloade data og geospatiale formfiler:

download valgresultater i Pennsylvania 2016 efter amt og amt shapefiles Valgdatafil og shapefile. Sharon Machlis

Jeg indlæser først nogle pakker: dplyr, lim, skalaer, htmltools, sf og folder. Jeg bruger rio til at importere data-CSV-filen, så du vil også have det på dit system.

bibliotek (dplyr); bibliotek (lim); bibliotek (skalaer);

bibliotek (htmltools); bibliotek (sf); bibliotek (folder)

pa_data <- rio :: import ("pa_2016_presidential.csv")

Dataimport og forberedelse

Dernæst bruger jeg sf'er st_read () funktion til at importere en shapefile af Pennsylvania amter.

pa_geo <- sf :: st_read ("PaCounty2020_08 / PaCounty2020_08.shp",

stringsAsFactors = FALSE)

Jeg kan ikke lide amtssøjlenavnet COUNTY_NAM i pa_geo, så jeg ændrer det til "Amt" med denne kode:

navne (pa_geo) [2] <- "County"

Inden jeg fletter mine data med min geografi, vil jeg sikre mig, at amtsnavne er de samme i begge filer. dplyr's anti_tilslut () funktion fletter to datasæt og viser hvilke rækker gør det ikke have en kamp. Jeg gemmer resultaterne i en dataramme kaldet problemer og ser på de første seks rækker med head () og de første tre kolonner:

problemer <- anti_join (pa_geo, pa_data, by = "County")

hoved (problemer [, 1: 3])

MSLINK County COUNTY_NUM geometri 1 42 MCKEAN 42 MULTIPOLYGON (((-78.20638 4 ...

Der er en problemrække. Det skyldes, at McKean County er MCKEAN i disse data, men McKEAN i den anden dataramme. Jeg ændrer McKean til at være alle caps i pa_data og kører anti_tilslut () Tjek igen.

pa_data $ County [pa_data $ County == "McKEAN"] <- "MCKEAN"

anti_join (pa_geo, pa_data, by = "County")

Der skal nu ikke være nogen problemrækker.

Den næste kodelinje fletter dataene med geografien:

pa_map_data <- flet (pa_geo, pa_data, efter = "County")

Endelig vil jeg sørge for, at min nye geografi og dataobjekt bruger det samme projektion som mine brochurer gør. Projektion er et ret komplekst GIS-emne. Indtil videre skal du bare vide, at jeg har brug for WGS84 for at matche indlægssedlen. Denne kode indstiller min projektion:

pa_map_data <- st_transform (pa_map_data, "+ proj = longlat + datum = WGS84")

Nu hvor mine data er i den form, jeg har brug for, har jeg yderligere tre opgaver: Opret farvepaletter til hver kandidat, opret pop op-vinduer til kortet og kod derefter selve kortet.

Farvepaletter

Jeg begynder med paletterne.

Jeg skal kortlægge rå stemmeforskelle i denne demo, men du vil måske bruge procentforskelle i stedet. Den første linje i koden nedenfor bruger base R'er rækkevidde() funktion for at få de mindste og største stemmeforskelle i Margin-kolonnen. Jeg har tildelt den mindste farve til det mindste antal og den mørkeste til det største antal.

Dernæst opretter jeg to paletter, der bruger den konventionelle røde til republikanere og blå til demokrater. Jeg bruger den samme intensitetsskala for begge paletter: lettest for den laveste margen, uanset kandidat og højest for den højeste margen, uanset kandidat. Dette vil give mig en idé om, hvor hver kandidat var stærkest på en enkelt intensitetsskala. Jeg bruger foldere colorNumeric () funktion med en paletfarve på rød eller blå for at oprette paletterne. (Det domæne argument angiver minimums- og maksimumværdier for farveskalaen.)

min_max_values ​​<- range (pa_map_data $ Margin, na.rm = TRUE)

trump_palette <- colorNumeric (palette = "Reds",

domæne = c (min_max_values ​​[1], min_max_values ​​[2]))

clinton_palette <- colorNumeric (palette = "Blues",

domæne = c (min_max_values ​​[1], min_max_values ​​[[2]]))

Den næste kodegruppe opretterto forskellige datarammer: Én for hver kandidat, der kun indeholder de steder, som kandidaten vandt. At have to datarammer hjælper mig med at få fin kontrol over pop-ups og farver. Jeg kan endda bruge forskellige pop op-tekster til hver.

trump_df <- pa_map_data [pa_map_data $ Winner == "Trump",]

clinton_df <- pa_map_data [pa_map_data $ Winner == "Clinton",]

Pop ups

Næste opgave er disse pop op-vinduer. Nedenfor genererer jeg nogle HTML inklusivestærk tags til fed tekst og br tags til linjeskift. Hvis du ikke er fortrolig med lim, er koden inden for {} seler variabler, der evalueres. I pop op-vinduerne viser jeg den vindende kandidats navn efterfulgt af deres stemmesum, den anden kandidats navn og stemmetotal og sejrsmargenen i dette amt. Detskalaer :: komma () funktionen tilføjer et komma til det numeriske stemmesum på tusind eller mere, ognøjagtighed = 1 sørger for, at det er et rundt heltal uden decimaler.

Koden rør derefter det lim() tekststreng til htmltools 'HTML () funktion, hvilken folder skal vise pop-up-teksten korrekt.

trump_popup <- lim ("{trump_df $ County} LAND

Vinder: Trump

Trump: {skalerer :: komma (trump_df $ Trump, nøjagtighed = 1)}

Clinton: {skalerer :: komma (trump_df $ Clinton, nøjagtighed = 1)}

Margen: {skalaer :: komma (trump_df $ Margen, nøjagtighed = 1)} ")%>%

lapply (htmltools :: HTML)

clinton_popup <- lim ("{clinton_df $ County} LAND

Vinder: Clinton

Clinton: {skalaer :: komma (clinton_df $ Clinton, nøjagtighed = 1)}

Trump: {skalaer :: komma (clinton_df $ Trump, nøjagtighed = 1)}

Margen: {skalaer :: komma (clinton_df $ Margin, nøjagtighed = 1)} ")%>%

lapply (htmltools :: HTML)

Kortkode

Endelig kortet. Kortkoden starter med at oprette et grundlæggende brochureobjekt ved hjælp af folder () uden tilføje data som et argument i hovedobjektet. Det skyldes, at jeg bruger to forskellige datasæt. Den næste linje i koden nedenfor indstiller baggrundsfliserne til CartoDB Positron. (Det er valgfrit. Du kan bruge standardindstillingen, men jeg kan lide den stil.)

indlægsseddel ()%>%

addProviderTiles ("CartoDB.Positron")

Dernæst bruger jeg folder tilføj polygoner () funktion to gange, en for hver kandidats dataramme overlejret på det samme kortlag.

indlægsseddel ()%>%

addProviderTiles ("CartoDB.Positron")%>%

tilføj polygoner (

data = trump_df,

fillColor = ~ trump_palette (trump_df $ Margin),

label = trump_popup,

slagtilfælde = SAND,

smoothFactor = 0,2,

fillOpacity = 0,8,

color = "# 666",

vægt = 1

) %>%

tilføj polygoner (

data = clinton_df,

fillColor = ~ clinton_palette (clinton_df $ Margin),

label = clinton_popup,

slagtilfælde = SAND,

smoothFactor = 0,2,

fillOpacity = 0,8,

color = "# 666",

vægt = 1

)

I ovenstående kodeblok indstiller jeg dataene for hver tilføj polygoner () funktion til hver kandidats dataramme. Det fillColor argument tager hver kandidats palet og anvender den på deres sejrsmargen. Pop-up (faktisk en rollover etiket) vil være kandidatens HTML, som jeg oprettede ovenfor.

Resten er standard design. slag indstiller en kantlinje omkring hver polygon. smoothFactor forenkler polygon-omridsvisningen; Jeg kopierede værdien fra et RStudio-demo-kort, jeg kunne lide. Og fillOpacity er, hvad du ville forvente.

farve er farven på polygon kantlinje, ikke selve polygonen (polygonen farve blev sat med fillColor). vægt er tykkelsen af ​​polygongrænselinjen i pixels.

Denne kode genererer et kort som det nedenfor, men med den ekstra mulighed for at rulle musen over (eller trykke på mobil) og se underliggende data.

Sharon Machlis,

Philadelphia er nederst til højre. Du kan se, hvor vigtigt det er, befolkningsmæssigt, sammenlignet med alle andre områder i Pennsylvania, der er store på kortet, men som har langt færre vælgere.

Sharon Machlis,

Det kan være interessant at kortlægge forskel i rå stemmemargener mellem et valg og et andet, såsom Pennsylvania i 2016 mod 2020. Det kort viser, hvor mønstre forskydes mest og kan hjælpe med at forklare ændringer i statlige resultater.

Hvis du er interesseret i flere valgdatavisualiseringer, har jeg gjort en valg2 R-pakke tilgængelig på GitHub. Du kan enten installere den som den er eller tjekke min R-kode på GitHub og skræddersy den til eget brug.

For flere R-tip, gå til siden Gør mere med R.

$config[zx-auto] not found$config[zx-overlay] not found