assignment 3

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(knitr)
hatecrimes <- read_csv("NYPD_Hate_Crimes_20261005.csv")
Rows: 4408 Columns: 14
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (9): Record Create Date, Patrol Borough Name, County, Law Code Category ...
dbl (4): Full Complaint ID, Complaint Year Number, Month Number, Complaint P...
lgl (1): Arrest Date

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
names(hatecrimes) <- tolower(names(hatecrimes))
names(hatecrimes) <- gsub(" ","",names(hatecrimes))
head(hatecrimes)
# A tibble: 6 × 14
  fullcomplaintid complaintyearnumber monthnumber recordcreatedate
            <dbl>               <dbl>       <dbl> <chr>           
1         2.02e14                2019           1 01/23/2019      
2         2.02e14                2019           2 02/25/2019      
3         2.02e14                2019           2 02/27/2019      
4         2.02e14                2019           4 04/16/2019      
5         2.02e14                2019           6 06/20/2019      
6         2.02e14                2019           7 07/31/2019      
# ℹ 10 more variables: complaintprecinctcode <dbl>, patrolboroughname <chr>,
#   county <chr>, lawcodecategorydescription <chr>, offensedescription <chr>,
#   pdcodedescription <chr>, biasmotivedescription <chr>,
#   offensecategory <chr>, arrestdate <lgl>, arrestid <chr>
bias_count <- hatecrimes |>
  select(biasmotivedescription) |>
  group_by(biasmotivedescription) |>
  count() |>
  arrange(desc(n))
head(bias_count)
# A tibble: 6 × 2
# Groups:   biasmotivedescription [6]
  biasmotivedescription          n
  <chr>                      <int>
1 ANTI-JEWISH                 2113
2 ANTI-MALE HOMOSEXUAL (GAY)   521
3 ANTI-ASIAN                   414
4 ANTI-BLACK                   341
5 ANTI-MUSLIM                  181
6 ANTI-OTHER ETHNICITY         174
ggplot(hatecrimes, aes(x = biasmotivedescription))+
  geom_bar()

bias_count |>
  head(10) |>
  ggplot(aes(x=biasmotivedescription, y = n)) +
  geom_col()

bias_count |>
  head(10) |>
  ggplot(aes(x=reorder(biasmotivedescription, n), y = n)) +
  geom_col() +
  coord_flip()

bias_count |>
  head(10) |>
  ggplot(aes(x=reorder(biasmotivedescription, n), y = n)) +
  geom_col() +
  coord_flip()+
  labs(x = "",
       y = "Counts of hatecrime types based on motive",
       title = "Bar Graph of Hate Crimes from 2019-2026",
       subtitle = "Counts based on the hatecrime motive",
       caption = "Source: NY State Division of Criminal Justice Services")

bias_count |>
  head(10) |>
  ggplot(aes(x=reorder(biasmotivedescription, n), y = n)) +
  geom_col(fill = "salmon") +
  coord_flip()+
  labs(x = "",
       y = "Counts of hatecrime types based on motive",
       title = "Bar Graph of Hate Crimes from 2019-2026",
       subtitle = "Counts based on the hatecrime motive",
       caption = "Source: NY State Division of Criminal Justice Services") +
  theme_minimal()

bias_count |>
  head(10) |>
  ggplot(aes(x=reorder(biasmotivedescription, n), y = n)) +
  geom_col(fill = "salmon") +
  coord_flip()+
  labs(x = "",
       y = "Counts of hatecrime types based on motive",
       title = "Bar Graph of Hate Crimes from 2019-2026",
       subtitle = "Counts based on the hatecrime motive",
       caption = "Source: NY State Division of Criminal Justice Services") +
  theme_minimal()+
  geom_text(aes(label = n), hjust = -.05, size = 3) +
  theme(axis.text.x = element_blank())

hate_year <- hatecrimes |>
  filter(biasmotivedescription %in% c("ANTI-JEWISH", "ANTI-MALE HOMOSEXUAL (GAY)", "ANTI-ASIAN", "ANTI-BLACK"))|>
  group_by(complaintyearnumber) |>
  count(biasmotivedescription)|>
  arrange(desc(n))
hate_year
# A tibble: 32 × 3
# Groups:   complaintyearnumber [8]
   complaintyearnumber biasmotivedescription          n
                 <dbl> <chr>                      <int>
 1                2024 ANTI-JEWISH                  371
 2                2023 ANTI-JEWISH                  342
 3                2025 ANTI-JEWISH                  340
 4                2022 ANTI-JEWISH                  280
 5                2019 ANTI-JEWISH                  252
 6                2021 ANTI-JEWISH                  215
 7                2026 ANTI-JEWISH                  187
 8                2021 ANTI-ASIAN                   150
 9                2020 ANTI-JEWISH                  126
10                2023 ANTI-MALE HOMOSEXUAL (GAY)   116
# ℹ 22 more rows
hate_county <- hatecrimes |>
  filter(biasmotivedescription %in% c("ANTI-JEWISH", "ANTI-MALE HOMOSEXUAL (GAY)", "ANTI-ASIAN", "ANTI-BLACK"))|>
  group_by(county) |>
  count(biasmotivedescription)|>
  arrange(desc(n))
hate_county
# A tibble: 20 × 3
# Groups:   county [5]
   county   biasmotivedescription          n
   <chr>    <chr>                      <int>
 1 KINGS    ANTI-JEWISH                  873
 2 NEW YORK ANTI-JEWISH                  711
 3 QUEENS   ANTI-JEWISH                  338
 4 NEW YORK ANTI-MALE HOMOSEXUAL (GAY)   252
 5 NEW YORK ANTI-ASIAN                   235
 6 KINGS    ANTI-MALE HOMOSEXUAL (GAY)   125
 7 BRONX    ANTI-JEWISH                  103
 8 KINGS    ANTI-BLACK                   101
 9 NEW YORK ANTI-BLACK                   101
10 QUEENS   ANTI-MALE HOMOSEXUAL (GAY)    96
11 RICHMOND ANTI-JEWISH                   88
12 KINGS    ANTI-ASIAN                    85
13 QUEENS   ANTI-ASIAN                    79
14 QUEENS   ANTI-BLACK                    75
15 BRONX    ANTI-MALE HOMOSEXUAL (GAY)    42
16 RICHMOND ANTI-BLACK                    35
17 BRONX    ANTI-BLACK                    29
18 BRONX    ANTI-ASIAN                    10
19 RICHMOND ANTI-MALE HOMOSEXUAL (GAY)     6
20 RICHMOND ANTI-ASIAN                     5
hate2 <- hatecrimes |>
  filter(biasmotivedescription %in% c("ANTI-JEWISH", "ANTI-MALE HOMOSEXUAL (GAY)", "ANTI-ASIAN", "ANTI-BLACK"))|>
  group_by(complaintyearnumber, county) |>
  count(biasmotivedescription)|>
  arrange(desc(n))
hate2
# A tibble: 143 × 4
# Groups:   complaintyearnumber, county [40]
   complaintyearnumber county   biasmotivedescription     n
                 <dbl> <chr>    <chr>                 <int>
 1                2024 KINGS    ANTI-JEWISH             151
 2                2025 KINGS    ANTI-JEWISH             142
 3                2024 NEW YORK ANTI-JEWISH             137
 4                2019 KINGS    ANTI-JEWISH             128
 5                2023 KINGS    ANTI-JEWISH             126
 6                2022 KINGS    ANTI-JEWISH             125
 7                2025 NEW YORK ANTI-JEWISH             124
 8                2023 NEW YORK ANTI-JEWISH             123
 9                2022 NEW YORK ANTI-JEWISH             104
10                2021 NEW YORK ANTI-ASIAN               84
# ℹ 133 more rows
ggplot(data = hate2) +
  geom_bar(aes(x=complaintyearnumber, y=n, fill = biasmotivedescription),
           position = "dodge", stat = "identity") +
  labs(fill = "Hate Crime Type",
       y = "Number of Hate Crime Incidents",
       title = "Hate Crime Type in NY Counties Between 2010-2016",
       caption = "Source: NY State Division of Criminal Justice Services")

ggplot(data = hate2) +
  geom_bar(aes(x=county, y=n, fill = biasmotivedescription),
           position = "dodge", stat = "identity") +
  labs(fill = "Hate Crime Type",
       y = "Number of Hate Crime Incidents",
       title = "Hate Crime Type in NY Counties Between 2010-2016",
       caption = "Source: NY State Division of Criminal Justice Services")

ggplot(data = hate2) +
  geom_bar(aes(x=complaintyearnumber, y=n, fill = biasmotivedescription),
           position = "dodge", stat = "identity") +
  facet_wrap(~county) +
  labs(fill = "Hate Crime Type",
       y = "Number of Hate Crime Incidents",
       title = "Hate Crime Type in NY Counties Between 2010-2016",
       caption = "Source: NY State Division of Criminal Justice Services")

nypop <- read_csv("nyc_census_pop_2020.csv")
Rows: 62 Columns: 4
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): Area Name, Population Percent Change
num (2): 2020 Census Population, Population Change

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
nypop$`Area Name` <- gsub(" County", "", nypop$`Area Name`)
nypop2 <- nypop |>
  rename(county = `Area Name`)|>
  select(county, `2020 Census Population`)
head(nypop2)
# A tibble: 6 × 2
  county      `2020 Census Population`
  <chr>                          <dbl>
1 Albany                        314848
2 Allegany                       46456
3 Bronx                        1472654
4 Broome                        198683
5 Cattaraugus                    77042
6 Cayuga                         76248
datajoin <- left_join(hate2, nypop2, by=c("county"))
datajoin
# A tibble: 143 × 5
# Groups:   complaintyearnumber, county [40]
   complaintyearnumber county biasmotivedescription     n 2020 Census Populati…¹
                 <dbl> <chr>  <chr>                 <int>                  <dbl>
 1                2024 KINGS  ANTI-JEWISH             151                     NA
 2                2025 KINGS  ANTI-JEWISH             142                     NA
 3                2024 NEW Y… ANTI-JEWISH             137                     NA
 4                2019 KINGS  ANTI-JEWISH             128                     NA
 5                2023 KINGS  ANTI-JEWISH             126                     NA
 6                2022 KINGS  ANTI-JEWISH             125                     NA
 7                2025 NEW Y… ANTI-JEWISH             124                     NA
 8                2023 NEW Y… ANTI-JEWISH             123                     NA
 9                2022 NEW Y… ANTI-JEWISH             104                     NA
10                2021 NEW Y… ANTI-ASIAN               84                     NA
# ℹ 133 more rows
# ℹ abbreviated name: ¹​`2020 Census Population`
hate_new <- hate2 |>
  mutate(county = as_factor(str_to_lower(as.character(county))))
nypop_new <- nypop2 |>
  mutate(county = as_factor(str_to_lower(as.character(county))))
datajoin <- left_join(hate_new, nypop_new, by=c("county"))
datajoin
# A tibble: 143 × 5
# Groups:   complaintyearnumber, county [40]
   complaintyearnumber county biasmotivedescription     n 2020 Census Populati…¹
                 <dbl> <fct>  <chr>                 <int>                  <dbl>
 1                2024 kings  ANTI-JEWISH             151                2736074
 2                2025 kings  ANTI-JEWISH             142                2736074
 3                2024 new y… ANTI-JEWISH             137                1694251
 4                2019 kings  ANTI-JEWISH             128                2736074
 5                2023 kings  ANTI-JEWISH             126                2736074
 6                2022 kings  ANTI-JEWISH             125                2736074
 7                2025 new y… ANTI-JEWISH             124                1694251
 8                2023 new y… ANTI-JEWISH             123                1694251
 9                2022 new y… ANTI-JEWISH             104                1694251
10                2021 new y… ANTI-ASIAN               84                1694251
# ℹ 133 more rows
# ℹ abbreviated name: ¹​`2020 Census Population`
datajoinrate <- datajoin |>
  mutate(rate = n/`2020 Census Population`* 100000) |>
  arrange(desc(rate))
datajoinrate
# A tibble: 143 × 6
# Groups:   complaintyearnumber, county [40]
   complaintyearnumber county biasmotivedescription     n 2020 Census Populati…¹
                 <dbl> <fct>  <chr>                 <int>                  <dbl>
 1                2024 new y… ANTI-JEWISH             137                1694251
 2                2025 new y… ANTI-JEWISH             124                1694251
 3                2023 new y… ANTI-JEWISH             123                1694251
 4                2022 new y… ANTI-JEWISH             104                1694251
 5                2024 kings  ANTI-JEWISH             151                2736074
 6                2025 kings  ANTI-JEWISH             142                2736074
 7                2021 new y… ANTI-ASIAN               84                1694251
 8                2021 new y… ANTI-JEWISH              84                1694251
 9                2019 kings  ANTI-JEWISH             128                2736074
10                2023 kings  ANTI-JEWISH             126                2736074
# ℹ 133 more rows
# ℹ abbreviated name: ¹​`2020 Census Population`
# ℹ 1 more variable: rate <dbl>

The first thing I noticed when I looked at the (multi-colored) bar graphed data was that anti-Jewish hate crimes were the highest in every part of New York. (Besides New York City) I would not necessarily call this a bad thing that every other minority in the set has far less hate crimes in comparison. I only see this as a little misleading to someone who may not be up to speed on a topic like this, I think the data frames the hate crimes in a way that would make an ignorant person believe that the non-Jewish hate crimes probably are not as serious because they happen so much less frequently. On the positive side, I will say that the color coding on the bar graph makes it very clear as to the proportion of occurring hate crimes in every city. Something I would like to learn about this dataset isn’t about this dataset from 2019-2026 specifically, but I would like to know the hate crime rate in New York historically, just to see if anti-Jewish hate crimes are anything recent. Another thing I would like to learn about this dataset is why there is a massive spike in anti-Asian hate crimes in New York City particularly.