Προγραμματισμός

Πώς να δημιουργήσετε έναν χάρτη εκλογών στο R

Εάν χαρτογραφείτε τα αποτελέσματα των εκλογών, ας πούμε, των προεδρικών εκλογών των ΗΠΑ ανά κράτος, είναι λογικό να δείξετε μόνο ένα κόκκινο χρώμα για τα κράτη που κέρδισαν οι Ρεπουμπλικάνοι και ένα χρώμα μπλε για τα κράτη που κέρδισαν οι Δημοκρατικοί. Αυτό συμβαίνει επειδή δεν έχει σημασία αν ένας υποψήφιος κερδίζει με τρεις χιλιάδες ψήφους ή τρία εκατομμύρια: Είναι «νικητής πάρτε όλα».

Αλλά κατά την ανάλυση των αποτελεσμάτων ενός κρατικές εκλογές με κομητεία, ή α εκλογές σε όλη την πόλη με περίβολος, το περιθώριο έχει σημασία. Είναι το συνολικό σύνολο που αποφασίζει τον νικητή. Το να κερδίσετε το ίδιο το "Atlanta" δεν είναι το μόνο που χρειάζεται να ξέρετε όταν κοιτάζετε τα αποτελέσματα της Γεωργίας για τον κυβερνήτη, για παράδειγμα. Θα θέλατε να μάθετε πόσες ψήφους κέρδισε ο Δημοκρατικός με, και να το συγκρίνουμε με άλλους τομείς.

Γι 'αυτό μου αρέσει να δημιουργώ χάρτες με χρωματική κωδικοποίηση από τον νικητή και με ένταση χρώματος που δείχνει περιθώριο νίκης. Αυτό σας λέει ποιες περιοχές συνέβαλαν περισσότερο και ποιες συνέβαλαν λιγότερο στο συνολικό αποτέλεσμα.

Σε αυτό το demo, θα χρησιμοποιήσω τα προεδρικά αποτελέσματα της Πενσυλβανίας 2016. Αν θέλετε να ακολουθήσετε, κατεβάστε τα δεδομένα και τα γεωγραφικά σχήματα:

κατεβάστε τα αποτελέσματα των εκλογών της Πενσυλβανίας 2016 ανά νομό και κομητεία shapefiles Αρχείο δεδομένων εκλογών και shapefile. Sharon Machlis

Φορτώω πρώτα μερικά πακέτα: dplyr, κόλλα, ζυγαριά, htmltools, sf και φυλλάδιο. Θα χρησιμοποιήσω το rio για να εισαγάγω το αρχείο δεδομένων CSV, οπότε θα το θέλετε και στο σύστημά σας.

βιβλιοθήκη (dplyr); βιβλιοθήκη (κόλλα) βιβλιοθήκη (κλίμακες);

βιβλιοθήκη (htmltools); βιβλιοθήκη (sf); βιβλιοθήκη (φυλλάδιο)

pa_data <- rio :: εισαγωγή ("pa_2016_presidential.csv")

Εισαγωγή και προετοιμασία δεδομένων

Στη συνέχεια, χρησιμοποιώ sf's st_read () λειτουργία για την εισαγωγή shapefile των επαρχιών της Πενσυλβανίας.

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

stringsAsFactors = FALSE)

Δεν μου αρέσει το όνομα στήλης κομητείας COUNTY_NAM στο pa_geo, επομένως θα το αλλάξω σε "Νομός" με αυτόν τον κωδικό:

ονόματα (pa_geo) [2] <- "Νομός"

Πριν συγχωνεύσω τα δεδομένα μου με τη γεωγραφία μου, θέλω να βεβαιωθώ ότι τα ονόματα των κομητειών είναι τα ίδια και στα δύο αρχεία. dplyr's anti_join () Η συνάρτηση συγχωνεύει δύο σύνολα δεδομένων και δείχνει ποιες σειρές όχι να έχεις έναν αγώνα. Θα αποθηκεύσω τα αποτελέσματα σε ένα πλαίσιο δεδομένων που ονομάζεται προβλήματα και θα κοιτάξω τις πρώτες έξι σειρές με κεφαλή () και τις τρεις πρώτες στήλες:

προβλήματα <- anti_join (pa_geo, pa_data, by = "County")

κεφάλι (προβλήματα [, 1: 3])

MSLINK County COUNTY_NUM γεωμετρία 1 42 MCKEAN 42 MULTIPOLYGON (((-78.20638 4 ...

Υπάρχει μια σειρά προβλημάτων. Αυτό συμβαίνει επειδή η McKean County είναι MCKEAN σε αυτά τα δεδομένα, αλλά η McKEAN στο άλλο πλαίσιο δεδομένων. Θα αλλάξω το McKean να είναι όλα όρια στα pa_data και θα τρέξω το anti_join () Ελέγξετε ξανά.

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

anti_join (pa_geo, pa_data, από = "County")

Τώρα δεν πρέπει να υπάρχουν προβλήματα.

Η επόμενη γραμμή κώδικα συγχωνεύει τα δεδομένα με τη γεωγραφία:

pa_map_data <- συγχώνευση (pa_geo, pa_data, by = "County")

Τέλος, θα βεβαιωθώ ότι το νέο αντικείμενο γεωγραφίας και δεδομένων χρησιμοποιεί το ίδιο προβολή όπως κάνουν τα πλακίδια φυλλαδίων μου. Η προβολή είναι ένα πολύ περίπλοκο θέμα GIS. Προς το παρόν, απλώς ξέρω ότι χρειάζομαι το WGS84 για να ταιριάξω με το φυλλάδιο. Αυτός ο κωδικός ορίζει την προβολή μου:

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

Τώρα που τα δεδομένα μου είναι στο σχήμα που χρειάζομαι, έχω τρεις ακόμη εργασίες: Δημιουργήστε παλέτες χρωμάτων για κάθε υποψήφιο, δημιουργήστε αναδυόμενα παράθυρα για το χάρτη και, στη συνέχεια, κωδικοποιήστε τον ίδιο τον χάρτη.

Παλέτες χρωμάτων

Θα ξεκινήσω με τις παλέτες.

Θα χαρτογραφήσω πρώτες διαφορές ψήφου σε αυτό το demo, αλλά ίσως θέλετε να χρησιμοποιήσετε ποσοστιαίες διαφορές. Η πρώτη γραμμή στον παρακάτω κώδικα χρησιμοποιεί τη βάση R εύρος() λειτουργία για να λάβετε τις μικρότερες και μεγαλύτερες διαφορές ψήφου στη στήλη Περιθώριο. Έχω εκχωρήσει το πιο ελαφρύ χρώμα στον μικρότερο αριθμό και το πιο σκοτεινό στον μεγαλύτερο αριθμό.

Στη συνέχεια δημιουργώ δύο παλέτες, χρησιμοποιώντας το συμβατικό κόκκινο για τους Ρεπουμπλικάνους και το μπλε για τους Δημοκρατικούς. Χρησιμοποιώ την ίδια κλίμακα έντασης και για τις δύο παλέτες: ελαφρύτερο για το χαμηλότερο περιθώριο, ανεξάρτητα από τον υποψήφιο και υψηλότερο για το υψηλότερο περιθώριο, ανεξάρτητα από τον υποψήφιο. Αυτό θα μου δώσει μια ιδέα για το πού κάθε υποψήφιος ήταν ισχυρότερος σε μία κλίμακα έντασης. Χρησιμοποιώ φυλλάδιο colorNumeric () λειτουργία, με ένα χρώμα παλέτας των κόκκινων ή μπλε, για να δημιουργήσετε τις παλέτες. (Ο τομέα Το όρισμα ορίζει ελάχιστες και μέγιστες τιμές για την κλίμακα χρώματος.)

min_max_values ​​<- εύρος (pa_map_data $ Margin, na.rm = TRUE)

trump_palette <- colorNumeric (παλέτα = "Κόκκινοι",

domain = c (min_max_values ​​[1], min_max_values ​​[2]))

clinton_palette <- colorNumeric (παλέτα = "Blues",

domain = c (min_max_values ​​[1], min_max_values ​​[[2]]))

Δημιουργείται η επόμενη ομάδα κώδικαδύο διαφορετικά πλαίσια δεδομένων: Ένα για κάθε υποψήφιο, που περιέχει μόνο τις θέσεις που κέρδισε ο υποψήφιος. Έχοντας δύο πλαίσια δεδομένων με βοηθά να αποκτήσω καλό έλεγχο των αναδυόμενων παραθύρων και των χρωμάτων. Μπορώ ακόμη και να χρησιμοποιήσω διαφορετικό αναδυόμενο κείμενο για κάθε ένα.

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

clinton_df <- pa_map_data [pa_map_data $ Winner == "Κλίντον",]

Αναδυόμενα παράθυρα

Επόμενη εργασία είναι αυτά τα αναδυόμενα παράθυρα. Παρακάτω δημιουργώ HTMLισχυρός ετικέτες για έντονο κείμενο και αδερ ετικέτες για αλλαγές γραμμής. Εάν δεν είστε εξοικειωμένοι με την κόλλα, ο κώδικας εντός των {} τιράντες είναι μεταβλητές που αξιολογούνται. Στα αναδυόμενα παράθυρα, θα εμφανίσω το όνομα του νικητή υποψηφίου ακολουθούμενο από το σύνολο των ψήφων τους, το όνομα του άλλου υποψηφίου και το σύνολο των ψήφων και το περιθώριο νίκης σε αυτήν την κομητεία. οκλίμακες :: κόμμα () Η συνάρτηση προσθέτει κόμμα σε αριθμητικά σύνολα ψήφων χίλια ή περισσότερα, καιακρίβεια = 1 διασφαλίζει ότι είναι ένας στρογγυλός ακέραιος αριθμός χωρίς δεκαδικά ψηφία.

Ο κώδικας στη συνέχεια διοχετεύει αυτό κόλλα() συμβολοσειρά κειμένου σε htmltools ’HTML () λειτουργία, το οποίο πρέπει να εμφανίζει σωστά το αναδυόμενο κείμενο.

trump_popup <- κόλλα ("{trump_df $ County} COUNTY

Νικητής: Trump

Trump: {scales :: comma (trump_df $ Trump, ακρίβεια = 1)}

Κλίντον: {κλίμακες :: κόμμα (trump_df $ Κλίντον, ακρίβεια = 1)}

Περιθώριο: {scales :: comma (trump_df $ Margin, correctness = 1)} ")%>%

lapply (htmltools :: HTML)

clinton_popup <- κόλλα ("{clinton_df $ County} COUNTY

Νικητής: Κλίντον

Κλίντον: {κλίμακες :: κόμμα (clinton_df $ Κλίντον, ακρίβεια = 1)}

Trump: {scales :: comma (clinton_df $ Trump, ακρίβεια = 1)}

Περιθώριο: {κλίμακες :: κόμμα (clinton_df $ Margin, ακριβείας = 1)} ")%>%

lapply (htmltools :: HTML)

Κωδικός χάρτη

Επιτέλους, ο χάρτης. Ο κωδικός χάρτη ξεκινά με τη δημιουργία ενός βασικού αντικειμένου φυλλαδίου χρησιμοποιώντας φυλλάδιο() χωρίς προσθήκη δεδομένων ως όρισμα στο κύριο αντικείμενο. Αυτό συμβαίνει επειδή θα χρησιμοποιώ δύο διαφορετικά σύνολα δεδομένων. Η επόμενη γραμμή στον παρακάτω κώδικα ορίζει τα πλακίδια φόντου στο CartoDB Positron. (Αυτό είναι προαιρετικό. Μπορείτε να χρησιμοποιήσετε την προεπιλογή, αλλά μου αρέσει αυτό το στυλ.)

φυλλάδιο ()%>%

addProviderTiles ("CartoDB.Positron")

Στη συνέχεια θα χρησιμοποιήσω φυλλάδιο addPolygons () λειτουργεί δύο φορές, ένα για το πλαίσιο δεδομένων κάθε υποψηφίου επικαλύπτεται στο ίδιο επίπεδο χάρτη.

φυλλάδιο ()%>%

addProviderTiles ("CartoDB.Positron")%>%

addPolygons (

δεδομένα = trump_df,

fillColor = ~ trump_palette (trump_df $ Margin),

label = trump_popup,

εγκεφαλικό = αληθινό,

smoothFactor = 0,2,

fillOpacity = 0,8,

χρώμα = "# 666",

βάρος = 1

) %>%

addPolygons (

δεδομένα = clinton_df,

fillColor = ~ clinton_palette (clinton_df $ Margin),

ετικέτα = clinton_popup,

εγκεφαλικό = αληθινό,

smoothFactor = 0,2,

fillOpacity = 0,8,

χρώμα = "# 666",

βάρος = 1

)

Στο παραπάνω μπλοκ κώδικα, ορίζω τα δεδομένα για κάθε ένα addPolygons () λειτουργία στο πλαίσιο δεδομένων κάθε υποψηφίου. ο χρώμα γεμίσματος Το επιχείρημα παίρνει την παλέτα κάθε υποψηφίου και το εφαρμόζει στο περιθώριο νίκης τους. Το αναδυόμενο παράθυρο (στην πραγματικότητα μια ανατροπή επιγραφή) θα είναι το HTML του υποψηφίου, το οποίο δημιούργησα παραπάνω.

Τα υπόλοιπα είναι στάνταρ σχεδιασμός. Εγκεφαλικό ορίζει μια οριακή γραμμή γύρω από κάθε πολύγωνο. smoothFactor απλοποιεί την οθόνη περιγράμματος πολυγώνου. Αντιγράψαμε την τιμή από έναν χάρτη επίδειξης RStudio που μου άρεσε. Και fillOpacity είναι αυτό που θα περίμενε κανείς.

χρώμα είναι το χρώμα του περίγραμμα πολυγώνου, όχι το ίδιο το πολύγωνο (το πολύγωνο χρώμα ορίστηκε με χρώμα γεμίσματος). βάρος είναι το πάχος της γραμμής περιγράμματος πολυγώνου σε pixel.

Αυτός ο κώδικας δημιουργεί έναν χάρτη όπως ο παρακάτω, αλλά με την προστιθέμενη δυνατότητα να μετακινείτε το ποντίκι σας (ή να πατάτε σε κινητό) και να βλέπετε τα υποκείμενα δεδομένα.

Sharon Machlis,

Η Φιλαδέλφεια βρίσκεται κάτω δεξιά. Μπορείτε να δείτε πόσο σημαντικό είναι, από άποψη πληθυσμού, σε σύγκριση με όλες τις άλλες περιοχές της Πενσυλβανίας που είναι μεγάλες στο χάρτη, αλλά έχουν πολύ λιγότερους ψηφοφόρους.

Sharon Machlis,

Ίσως είναι ενδιαφέρον να χαρτογραφήσετε το διαφορά σε ακατέργαστα περιθώρια ψήφου μεταξύ μιας εκλογής και μιας άλλης, όπως η Πενσυλβανία το 2016 έναντι του 2020. Αυτός ο χάρτης θα δείχνει πού άλλαξαν τα μοτίβα και θα μπορούσαν να βοηθήσουν στην εξήγηση αλλαγών στα αποτελέσματα σε ολόκληρη την πολιτεία.

Εάν ενδιαφέρεστε για περισσότερες απεικονίσεις δεδομένων εκλογών, έχω διαθέσει ένα πακέτο εκλογών2 R στο GitHub. Μπορείτε είτε να το εγκαταστήσετε ως έχει είτε να δείτε τον κωδικό R στο GitHub και να τον προσαρμόσετε για δική σας χρήση.

Για περισσότερες συμβουλές R, μεταβείτε στη σελίδα Do More With R.

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