1. Load Data
# Load data
files <- list.files(pattern = "*.csv")
list2env(
lapply(
setNames(files, make.names(str_to_lower(gsub("*.csv", "", files)))),
read_csv
),
envir = .GlobalEnv
)
## <environment: R_GlobalEnv>
# Check dataset
members_23 <- members.2.2023.01.10
glimpse(members_23)
## Rows: 761
## Columns: 46
## $ `Name (Prefix)` <lgl> …
## $ `Name (First)` <chr> …
## $ `Name (Middle)` <lgl> …
## $ `Name (Last)` <chr> …
## $ `Name (Suffix)` <lgl> …
## $ Phone <chr> …
## $ `Date of Birth` <date> …
## $ Gender <chr> …
## $ `American Indian or Alaska Native` <chr> …
## $ Asian <chr> …
## $ `Black or African American` <chr> …
## $ `Hispanic or Latino(a) or Spanish Origin` <chr> …
## $ `Native Hawaiian or Other Pacific Islander` <chr> …
## $ White <chr> …
## $ `2 or more races` <chr> …
## $ Other <chr> …
## $ Email <chr> …
## $ `Address (Street Address)` <chr> …
## $ `Address (Address Line 2)` <chr> …
## $ `Address (City)` <chr> …
## $ `Address (State / Province)` <chr> …
## $ `Address (ZIP / Postal Code)` <chr> …
## $ `Address (Country)` <lgl> …
## $ `Civilian or Veteran/Military member` <chr> …
## $ `Current Service Status (If applicable)` <chr> …
## $ `Branch of Service (if applicable)` <chr> …
## $ `Shirt Size` <chr> …
## $ `Tell us about yourself or what can we do to improve Chicago Veterans?` <chr> …
## $ Fundraising <chr> …
## $ `Events/Promotions` <chr> …
## $ `Employment/Resume Assistance` <chr> …
## $ Blogs <chr> …
## $ `Marketing/Social Media` <chr> …
## $ `General Volunteer (Working Party)` <chr> …
## $ `Educational Assistance` <chr> …
## $ `Created By (User Id)` <lgl> …
## $ `Entry Id` <dbl> …
## $ `Entry Date` <dttm> …
## $ `Source Url` <chr> …
## $ `Transaction Id` <lgl> …
## $ `Payment Amount` <lgl> …
## $ `Payment Date` <lgl> …
## $ `Payment Status` <lgl> …
## $ `Post Id` <lgl> …
## $ `User Agent` <chr> …
## $ `User IP` <chr> …
# Missing values
colSums(is.na(members_23))
## Name (Prefix)
## 761
## Name (First)
## 0
## Name (Middle)
## 761
## Name (Last)
## 0
## Name (Suffix)
## 761
## Phone
## 0
## Date of Birth
## 0
## Gender
## 0
## American Indian or Alaska Native
## 753
## Asian
## 725
## Black or African American
## 625
## Hispanic or Latino(a) or Spanish Origin
## 619
## Native Hawaiian or Other Pacific Islander
## 757
## White
## 485
## 2 or more races
## 730
## Other
## 743
## Email
## 0
## Address (Street Address)
## 0
## Address (Address Line 2)
## 544
## Address (City)
## 0
## Address (State / Province)
## 0
## Address (ZIP / Postal Code)
## 0
## Address (Country)
## 761
## Civilian or Veteran/Military member
## 0
## Current Service Status (If applicable)
## 0
## Branch of Service (if applicable)
## 0
## Shirt Size
## 0
## Tell us about yourself or what can we do to improve Chicago Veterans?
## 295
## Fundraising
## 575
## Events/Promotions
## 333
## Employment/Resume Assistance
## 520
## Blogs
## 667
## Marketing/Social Media
## 592
## General Volunteer (Working Party)
## 403
## Educational Assistance
## 571
## Created By (User Id)
## 761
## Entry Id
## 0
## Entry Date
## 0
## Source Url
## 0
## Transaction Id
## 761
## Payment Amount
## 761
## Payment Date
## 761
## Payment Status
## 761
## Post Id
## 761
## User Agent
## 0
## User IP
## 0
1.2 Clean columns
members_23 <- members_23 %>%
clean_names() %>%
mutate(
year_of_birth = year(date_of_birth), # only keep year
address_city = str_to_title(address_city),
race = as.factor(ifelse(
is.na(american_indian_or_alaska_native) == FALSE, # Alkaska/Native
"American Indian/Alaskan Native",
ifelse(
is.na(asian) == FALSE, # Asian
"Asian",
ifelse(
is.na(black_or_african_american) == FALSE,
"Black",
ifelse(
is.na(white) == FALSE,
"White",
ifelse(
is.na(native_hawaiian_or_other_pacific_islander) == FALSE,
"Hawaiian/Pacific Islander",
ifelse(
is.na(x2_or_more_races) == FALSE,
"Multirace",
NA
)
)
)
)
)
)),
hispanic = as.factor(ifelse(
is.na(hispanic_or_latino_a_or_spanish_origin) == FALSE, # Hispanic
"Hispanic",
NA
)),
across(civilian_or_veteran_military_member:branch_of_service_if_applicable,
as.factor), # Convert columns on veteran history, current veteran status and branch
event = as.factor(ifelse(
is.na(fundraising) == FALSE, # Fundraising
"Fundraising",
ifelse(
is.na(events_promotions) == FALSE, # Event promotion
"Event Promotions",
ifelse(
is.na(employment_resume_assistance) == FALSE,
"Employment", # Employment
ifelse(
is.na(blogs) == FALSE,
"Blog", # Blog
ifelse(
is.na(marketing_social_media) == FALSE,
"Media Marketing", # Marketing
ifelse(
is.na(general_volunteer_working_party) == FALSE,
"General Volunteer", # General Volunteer
ifelse(
is.na(educational_assistance) == FALSE,
"Education", # Education
NA
)
)
)
)
)
)
))
)
# Keep informative columns
members_23 <- members_23 %>%
rename(
"veteran" = "civilian_or_veteran_military_member",
"veteran_current" = "current_service_status_if_applicable",
"branch" = "branch_of_service_if_applicable"
) %>%
select(
name_first, name_last, phone:gender, email:address_zip_postal_code,
veteran:shirt_size, entry_date, year_of_birth:event
) %>%
select(
entry_date, name_first, name_last, phone, email,
year_of_birth, gender, race, hispanic,
veteran:branch, event, everything()
)
1.3 Remove Duplicates
dup <- members_23 %>%
get_dupes(
name_first, name_last, # same time
year_of_birth, gender, race, # same flight
veteran, branch
) %>%
group_by(name_first, name_last, year_of_birth, gender, phone) %>%
arrange(entry_date)
# Keep the latest submission
dup_keep <- dup %>%
slice_tail()
# Remove duplicated data from dup
dup <- anti_join(dup, dup_keep)
# Remove duplicates
members_23 <- anti_join(members_23, dup,
by = c("entry_date", "name_first", "name_last"))
# Remove wrong entries
dup_wrong <- members_23 %>%
get_dupes(name_first, name_last)
members_23_dup_edited <- members_23_dup_edited %>%
select(-date_of_birth)
dup_wrong <- anti_join(dup_wrong, members_23_dup_edited) %>%
filter(year_of_birth > 1900) # remove entries with birth year before 1900
# Final clean dataset without duplicates
members_23 <- anti_join(members_23, dup_wrong,
by = c("entry_date", "name_first", "name_last"))
# write_csv(members_23, "members_23_nodup.csv")
1.4. Clean Name data
members_23[!(nchar(members_23$name_first) < 2 | nchar(members_23$name_first) < 2), ]
## # A tibble: 611 × 20
## entry_date name_f…¹ name_…² phone email year_…³ gender race hispa…⁴
## <dttm> <chr> <chr> <chr> <chr> <dbl> <chr> <fct> <fct>
## 1 2023-01-07 04:22:52 Peter Stavro… (630… Psta… 1986 Male <NA> Hispan…
## 2 2023-01-06 23:58:22 Patrycja Saida (773… Patr… 1982 Female White <NA>
## 3 2023-01-06 14:09:49 Justin Wesley (708… just… 1983 Male White <NA>
## 4 2022-12-31 02:11:03 Jacob Alcaraz (910… jaco… 1986 Male Mult… <NA>
## 5 2022-12-29 21:54:03 Lexis Procha… (773… lexi… 1992 Female White <NA>
## 6 2022-12-29 16:08:40 Ismael Quinte… (815… Quin… 1982 Male <NA> Hispan…
## 7 2022-12-28 22:37:33 Kristin Davis (850… kayl… 1987 Female White <NA>
## 8 2022-12-28 04:01:42 Michael Atkins… (801… Mich… 1984 Male White <NA>
## 9 2022-12-27 02:17:42 Allison Lutes (312… alut… 1984 Female White <NA>
## 10 2022-12-27 02:08:56 Weston Polaski (312… wpol… 1983 Male White <NA>
## # … with 601 more rows, 11 more variables: veteran <fct>,
## # veteran_current <fct>, branch <fct>, event <fct>, date_of_birth <date>,
## # address_street_address <chr>, address_address_line_2 <chr>,
## # address_city <chr>, address_state_province <chr>,
## # address_zip_postal_code <chr>, shirt_size <chr>, and abbreviated variable
## # names ¹name_first, ²name_last, ³year_of_birth, ⁴hispanic
members_23 <- members_23 %>%
mutate(name_first = str_to_title(name_first),
name_last = str_to_title(name_last)) %>%
filter(name_first != "N")
1.5. Clean Age Data
members_23 <- members_23 %>%
filter(year_of_birth >= 1920) # Filter out people aged over 100
1.6. Correct Veteran Status
# Remove data with no veteran branch info
veteran_wrong <- members_23 %>%
filter(branch == "None" & veteran == "Veteran")
# Remove wrong entries
members_23 <- anti_join(members_23, veteran_wrong)
# Sanity Check
members_23 %>%
count(veteran, veteran_current, branch)
## # A tibble: 36 × 4
## veteran veteran_current branch n
## <fct> <fct> <fct> <int>
## 1 Civilian Civilian Air Force 1
## 2 Civilian Civilian Marine Corps 2
## 3 Civilian Civilian None 59
## 4 Civilian Civilian US Army 3
## 5 Civilian Civilian US Navy 7
## 6 Civilian Retired US Army 1
## 7 Veteran Active Duty Air Force 6
## 8 Veteran Active Duty Marine Corps 4
## 9 Veteran Active Duty National Guard 1
## 10 Veteran Active Duty US Army 13
## # … with 26 more rows
1.7. Clean Geographic Data
library(zipcodeR)
# Merge cleaned state data
zip_check <- members_23_zip_check_edited %>%
select(address_state_province, address_zip_postal_code,
entry_date, name_first, name_last, gender, race, year_of_birth)
# Merge
members_23 <- left_join(members_23, zip_check,
by = c("entry_date", "name_first", "name_last",
"gender", "race", "year_of_birth")) %>%
select(-ends_with(".x"))
# Rename address columns
colnames(members_23) <- gsub("\\..*", "", colnames(members_23))
# Incorporate city information
members_23 <- members_23 %>%
mutate(address_zip_postal_code = as.numeric(str_sub(address_zip_postal_code, 1, 5)),
address_zip_postal_code = as.character(sprintf("%05d", address_zip_postal_code))
)
# Zipcode merge
zip <- zip_code_db %>%
select(zipcode, major_city, state:lng)
members_23 <- members_23 %>%
left_join(zip, by = c("address_zip_postal_code" = "zipcode")) %>%
select(-state)
# NA Community zip code
zip_na_check <- members_23 %>%
filter(is.na(address_state_province))
# write_csv(zip_na_check, "zip_na_check.csv")
# Output dataset
write_csv(members_23, "members_23_clean.csv")
2. Summary Statistics
2.1. Unique number of each column
# Unique values of each column
values_unique <- vector("double", length(members_23))
names(values_unique) <- names(members_23)
for (i in names(members_23)) {
values_unique[i] <- n_distinct(members_23[i])
}
# View results
as.data.frame(values_unique)
## values_unique
## entry_date 606
## name_first 424
## name_last 526
## phone 597
## email 599
## year_of_birth 66
## gender 2
## race 7
## hispanic 2
## veteran 2
## veteran_current 6
## branch 7
## event 8
## date_of_birth 591
## address_street_address 596
## address_address_line_2 158
## address_city 191
## shirt_size 5
## address_state_province 21
## address_zip_postal_code 240
## major_city 166
## lat 119
## lng 110
2.2 Top cases of Each Columns
# Top cases
top_cases <- vector("list")
get_top_cases <- function(df, cols){
for (i in cols){ top_cases[[i]] <- df %>%
group_by(df[[i]]) %>%
summarise(count = n()) %>%
arrange(desc(count)) %>%
head(10)
colnames(top_cases[[i]]) <- c(i, "count")
}
top_cases
}
top_case_col <- c("year_of_birth", "gender",
"race", "veteran", "veteran_current", "branch",
"event", "address_city", "address_state_province")
get_top_cases(members_23, top_case_col)
## $year_of_birth
## # A tibble: 10 × 2
## year_of_birth count
## <dbl> <int>
## 1 1984 27
## 2 1989 25
## 3 1981 23
## 4 1986 20
## 5 1982 19
## 6 1983 19
## 7 1987 19
## 8 1980 18
## 9 1985 18
## 10 1990 18
##
## $gender
## # A tibble: 2 × 2
## gender count
## <chr> <int>
## 1 Male 374
## 2 Female 232
##
## $race
## # A tibble: 7 × 2
## race count
## <chr> <int>
## 1 <NA> 232
## 2 White 208
## 3 Black 107
## 4 Asian 30
## 5 Multirace 23
## 6 American Indian/Alaskan Native 5
## 7 Hawaiian/Pacific Islander 1
##
## $veteran
## # A tibble: 2 × 2
## veteran count
## <fct> <int>
## 1 Veteran 533
## 2 Civilian 73
##
## $veteran_current
## # A tibble: 6 × 2
## veteran_current count
## <fct> <int>
## 1 Civilian 368
## 2 Separated 79
## 3 Retired 50
## 4 Reserve 49
## 5 Active Duty 31
## 6 Medically Retired 29
##
## $branch
## # A tibble: 7 × 2
## branch count
## <fct> <int>
## 1 US Army 236
## 2 US Navy 111
## 3 Marine Corps 99
## 4 Air Force 71
## 5 None 59
## 6 National Guard 27
## 7 Coast Guard 3
##
## $event
## # A tibble: 8 × 2
## event count
## <fct> <int>
## 1 Event Promotions 210
## 2 Fundraising 146
## 3 <NA> 120
## 4 Employment 56
## 5 General Volunteer 33
## 6 Education 18
## 7 Media Marketing 13
## 8 Blog 10
##
## $address_city
## # A tibble: 10 × 2
## address_city count
## <chr> <int>
## 1 Chicago 308
## 2 Berwyn 8
## 3 Oak Park 6
## 4 Bolingbrook 5
## 5 Oak Lawn 5
## 6 Plainfield 5
## 7 Mount Prospect 4
## 8 Park Ridge 4
## 9 Schaumburg 4
## 10 Westchester 4
##
## $address_state_province
## # A tibble: 10 × 2
## address_state_province count
## <chr> <int>
## 1 IL 497
## 2 <NA> 73
## 3 TX 5
## 4 IN 3
## 5 NC 3
## 6 TN 3
## 7 VA 3
## 8 AE 2
## 9 AZ 2
## 10 CA 2
3. Plot
# Theme
chicago_veteran = "#304573"
theme <- theme_economist() +
theme(
plot.title = element_text(size = 12, face = "bold", vjust = 1.5),
plot.subtitle = element_text(size = 9, face = "italic", hjust = 0),
axis.title = element_text(size = 9, face = "bold"),
plot.caption = element_text(size = 6, face = "italic", hjust = 0),
axis.text = element_text(size = 8),
legend.key.size = unit(0.5, "cm"),
legend.text = element_text(size = 8),
legend.title = element_blank()
)
#one disaggregation variable
get_pct <- function(col, df) {
# get data frame
data_pct <- df %>%
group_by(df[[col]]) %>%
summarise(cases = n())
colnames(data_pct) <- c(col, "cases") # Change column name
data_pct[[col]] <- as.factor(data_pct[[col]]) # Factorize variable
data_pct
}
# Generate Plots
get_plt <- function(var, df) {
# wage gap ts
plt_pct <- df %>%
ggplot() +
geom_col(aes(var, cases,
fill = factor(df[[var]])),
position = "dodge") +
theme
plt_pct
}
3.1 Gender and Race Distribution
# Gender
gender_pct <- get_pct("gender", members_23)
gender_pct_plt <- ggplot(gender_pct) +
geom_col(aes(fct_reorder(gender, desc(cases)), cases, fill = gender)) +
labs(
title = "Members Gender Distribution",
x = "Gender",
y = "Number of Members"
) +
scale_y_continuous(
limits = c(0, 400),
breaks = seq(0, 400, 50)
) +
scale_fill_economist() +
theme
# Race
race_pct <- get_pct("race", members_23)
race_pct_plt <- ggplot(drop_na(race_pct)) +
geom_col(aes(fct_reorder(race, desc(cases)), cases, fill = race)) +
labs(
title = "Members Racial Identity Distribution",
x = "Race",
y = "Number of Members"
) +
scale_x_discrete(labels = function(x) str_wrap(x, width = 23)) +
scale_y_continuous(
limits = c(0, 230),
breaks = seq(0, 210, 30)
) +
scale_fill_economist() +
theme
# Plot
gender_pct_plt

race_pct_plt

3.2 Age Distribution
age_pct <- get_pct("year_of_birth", members_23)
veteran_pct_plt <- ggplot(age_pct) +
geom_col(aes(year_of_birth, cases)) +
labs(
title = "Age Distribution",
x = "Age",
y = "Number of Members"
) +
theme
3.2 Veteran Status Distrituion
# Veteran status
veteran_pct <- get_pct("veteran", members_23)
veteran_pct_plt <- ggplot(veteran_pct) +
geom_col(aes(fct_reorder(veteran, desc(cases)), cases, fill = veteran)) +
labs(
title = "Veteran Distribution",
x = "Veteran",
y = "Number of Members"
) +
scale_y_continuous(
limits = c(0, 550),
breaks = seq(0, 550, 50)
) +
theme
# Current veteran status
veteran_status_pct <- get_pct("veteran_current", members_23)
veteran_status_pct_plt <- ggplot(veteran_status_pct) +
geom_col(aes(fct_reorder(veteran_current, desc(cases)), cases, fill = veteran_current)) +
labs(
title = "Current Veteran Status",
x = "Current Veteran Status",
y = "Number of Members"
) +
scale_y_continuous(
limits = c(0, 400),
breaks = seq(0, 400, 50)
) +
scale_fill_economist() +
theme
# Branch served
branch_pct <- get_pct("branch", members_23)
branch_pct_plt <- ggplot(filter(branch_pct, branch != "None")) +
geom_col(aes(fct_reorder(branch, desc(cases)), cases, fill = branch)) +
labs(
title = "Distribution of Branch Served Among Veterans",
x = "Branch Served",
y = "Number of Members"
) +
scale_y_continuous(
limits = c(0, 250),
breaks = seq(0, 250, 50)
) +
scale_fill_economist() +
theme
# Plot
plt <- ggarrange(ggarrange(veteran_pct_plt, veteran_status_pct_plt, ncol = 2),
branch_pct_plt,
nrow = 2)
plt

3.4 Event of Interest
3.4.1 Event of Interest by Gender
plt_event_gender <- members_23 %>%
drop_na(event) %>%
count(event, gender) %>%
ggplot(aes(fct_reorder(event,desc(n)), n,
fill = factor(gender))
) +
geom_col(position = "dodge") +
labs(
title = "Event of Interest by Gender",
subtitle = "Event Promotion is the most popular; Preference is consistent across genders",
x = "Interested Event Type",
y = "Number of Responses") +
scale_y_continuous(limits = c(0, 180),
breaks = seq(0, 170, 30)) +
theme_economist() +
theme(
legend.position = c(0.09,0.95),
legend.direction = "horizontal") +
theme
plt_event_race <- members_23 %>%
drop_na(event, race) %>%
filter(race != "Multirace") %>%
group_by(race) %>%
mutate(event_total = n()) %>%
group_by(race, event) %>%
mutate(event_race = n()) %>%
distinct(race, event, .keep_all = TRUE) %>%
ggplot(aes(fct_reorder(race, -event_total), event_race,
fill = fct_rev(factor(event))
)) +
geom_col() +
labs(
title = "Event of Interest by Race",
x = "Race",
y = "Number of Responses") +
scale_x_discrete(labels = function(x) str_wrap(x, width = 20)) +
scale_y_continuous(limits = c(0, 220),
breaks = seq(0, 210, 30)) +
scale_fill_economist() +
theme
3.4.2 Event of Interest by Race
plt_event_gender

plt_event_race

members_23 %>%
drop_na(event, race) %>%
filter(race != "Multirace") %>%
group_by(race) %>%
mutate(total = n()) %>%
group_by(race, event) %>%
transmute(
total = total,
event_case = n(),
event_pct = event_case/total) %>%
distinct(.keep_all = FALSE) %>%
ggplot(aes(fct_reorder(event, -event_case), event_pct,
group = 1)) +
geom_col() +
labs(
title = "Event of Interest by Race",
subtitle = "Event Promotion is the most popular;Preference is consistent across genders",
x = "Interested Event Type",
y = "Number of Responses") +
scale_y_continuous(limits = c(0, 1),
breaks = seq(0, 1, 0.2)) +
facet_wrap(~race) +
theme

3.5 Spatial Analysis
3.5.1 Chicago Communities
# Clean zipcode
chicago <- members_23 %>%
arrange(desc(address_zip_postal_code)) %>%
mutate(address_zip_postal_code = str_sub(address_zip_postal_code, 1, 5),
zipcode = as.numeric(address_zip_postal_code)) %>%
drop_na(zipcode) %>%
mutate(zipcode = as.character(zipcode))
#Zipcode
geometry <- read_excel("uszips.xlsx")
geometry <- geometry %>%
filter(city == "Chicago") %>%
select(zip, lat, lng) %>%
mutate(zipcode = as.character(zip)) %>%
select(-1)
# Filter Chicago data
chicago <- inner_join(chicago, geometry, by = "zipcode")
#Geometry
community_shape <- st_read("Zip_Codes.shp")
## Reading layer `Zip_Codes' from data source
## `/Users/mia/Desktop/chicago-veterans/Zip_Codes.shp' using driver `ESRI Shapefile'
## Simple feature collection with 61 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 1090000 ymin: 1810000 xmax: 1210000 ymax: 1950000
## Projected CRS: NAD83 / Illinois East (ftUS)
glimpse(community_shape)
## Rows: 61
## Columns: 5
## $ OBJECTID <dbl> 33, 34, 35, 36, 37, 38, 39, 40, 1, 2, 3, 4, 5, 6, 7, 8, 9, …
## $ ZIP <chr> "60647", "60639", "60707", "60622", "60651", "60611", "6063…
## $ SHAPE_AREA <dbl> 106052287, 127476051, 45069038, 70853834, 99039621, 2350605…
## $ SHAPE_LEN <dbl> 42720, 48104, 27289, 42528, 47970, 34689, 67711, 48188, 339…
## $ geometry <MULTIPOLYGON [US_survey_foot]> MULTIPOLYGON (((1162711 191..., M…
# Clean shape dataset
community_shape <- community_shape %>%
rename("zipcode" = "ZIP") %>%
select(zipcode, geometry)
community_shape <- st_sf(community_shape)
# Merge
chicago_plt <- inner_join(chicago, community_shape, by = "zipcode")
chicago_plt_sf <- st_sf(chicago_plt)
Plot
chicago_plt_sf %>%
count(zipcode) %>%
ggplot() +
geom_sf(aes(fill = n)) +
labs(
title = "Chicago Veterans Members",
subtitle = "Year 2022-2023",
fill = element_blank()
) +
scale_fill_distiller(
palette = "Blues",
direction = 1
) + # darker color represents higher value
theme_economist() +
theme(
plot.title = element_text(
size = 12, face = "bold"
),
plot.subtitle = element_text(
size = 9, face = "italic",
vjust = -0.5,
hjust = 0
),
legend.text = element_text(size = 8),
legend.position = "right",
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank()
)

3.5.2 US State
library(tigris)
# 1.Members by State
us_geo <- states(cb = TRUE, resolution = '20m') %>%
select(STUSPS, geometry)
##
|
| | 0%
|
|= | 1%
|
|======= | 10%
|
|======== | 12%
|
|============ | 16%
|
|================== | 25%
|
|===================== | 29%
|
|======================== | 34%
|
|============================== | 43%
|
|================================= | 47%
|
|======================================== | 58%
|
|================================================ | 69%
|
|========================================================= | 82%
|
|============================================================ | 86%
|
|======================================================================| 100%
members_23_sf <- inner_join(members_23, us_geo, by = c("address_state_province" = "STUSPS")) %>%
group_by(address_state_province) %>%
mutate(members_cases = n()) %>%
st_as_sf()
#Plot
mapview(members_23_sf, zcol = "members_cases", col.regions = brewer.pal(-6, "RdBu"))
# 2.Members by City
members_city_sf <- members_23 %>%
drop_na(lng) %>%
st_as_sf(coords = c("lng", "lat"), crs = 4326)
mapview(members_23_sf, zcol = "members_cases", col.regions = brewer.pal(-6, "RdBu")) +
mapview(members_city_sf, cex = 3, alpha = 0.5, col.regions = "slateblue", legend = FALSE)