Dive Into South African Police Service Crime Stats:2022-2023

Author

Oselu Enabor

Published

2024-02-13

Abstract
Crime trends in South Africa have been on the increase since 1996 with major cities following the national trend. The increase in population, unequal wealth distribution, rising unemployment rates and erosion of public trust in the government due to corruption and malfeasance has not assisted in curbing the levels of crime. Crime statistics in the country are published by the South African Police Service, who are responsible for enforcing the laws and maintaining peace and order in the country. These statistics are published in collaboration with Statistics South Africa, the national statistical service of the nation. In this project, we analyse the crime trend in the country between 2013 and 2023.

1 Introduction: Crime situation in South Africa

South Africa has one of the highest-crime rate in the world - which includes high rates for crimes such as assaults, rape, murder, and other violent crimes. The high crime rate has been attributed to factors such as inadequate education, unemployment, poverty, and unequal distribution of resources (AKINOLA and Ohonba 2023; Bhorat et al. 2017; K. V. Brown 2001). Violent crimes such as rape and murder are on the increase compared to other crimes in the country (Glaser 2008). Crime rate has a negative effect on foreign investments and reduces the faith in the government and institutions tasked with public safety (L. Brown and Hibbert 2017).

1.1 Project description

The South African Police Service (SAPS) is the national police force of the Republic of South Africa. There are 1154 police stations in the country which are classified under provincial borders, with a provincial commissioner appointed for each of the 9 provinces in South Africa. The SAPS has 117950 officers who are responsible for the maintenance of public safety of 62 million South Africans. The SAPS in collaboration with Statistics South Africa (Stats SA), generate crime statistics quarterly and annually. The statistics are in line with international best practices and are used to inform the policy development planning in the criminal justice systems.

1.2 Objectives

The objectives of this data analysis project is as follows:

  • View the crime trends in the country

  • See which crimes are most common in each province

  • Give commentary on which areas need more police reinforcement based

Members of the South African Police Service (SAPS).

2 Methodology

SAPS Crime Data

According to the SAPS website, crimes reported are recorded as they are received (from either the victims, witnesses or third parties) by the police or when they are detected by the police, irrespective of when the crime(s) were committed or who committed them. Crime statistics are created from recording process where crime codes are allocated to a reported crime type. Police stations then aggregate the codes in order for the province and the national to synchronize computation and distribution of reports. The crime statics are focused on the 21 priority crimes grouped into two categories:

  1. 17 community-reported serious crimes

    • contact

    • contact-related

    • property-related

    • other serious crimes

  2. Crimes that are detected as a result of police action.

World Bank Datasets

The following were collected from World Bank Data and filtered to get South African records:

  • Gross Domestic Product (GDP) per capita

  • Unemployment (%total labour force)

  • Population

The methodology used to accomplish the project objectives is organised as follows. Firstly, the R libraries used are imported followed by the definition of custom-functions used to simply the analysis task . The raw data sets are imported and processed to make them analysis ready. An overview of South Africa is presented. This includes chosen statistics from the World Bank, and an overview of the make up of the country. The analysis of the processed crime data will start at the national level, then progress to the provincial level, and conclude at the station level within each province.

2.1 Install libraries

Code
install.packages(ggplot2)
install.packages(dplyr)
install.packages(tidyverse)
install.packages(janitor)
install.packages(here)
install.packages(gt)
install.packages(gtsummary)
install.packages(knitr)
install.packages(DT)
install.packages(maps)
install.packages(sf)
install.packages(leaflet)

2.2 Import libraries

Code
# load necessary libraries
library(ggplot2)
library(dplyr)
library(tidyverse)
library(ggcorrplot)
library(scales)
library(janitor)
library(here)
library(gt)
library(gtsummary)
library(knitr)
library(DT)
library(maps)
library(sf)
library(leaflet)

2.3 Functions

filter_df: This function is used to filter the main crime dataframe by each category of crimes. The function takes in 2 inputs:

  • df: an input dataframe

  • crime_list: a list of crimes used to filter the dataframe

The function returns a dataframe filtered by the crime_list.

Code
filter_df <- function(df, crime_list){
  df |> 
    filter(crime_category%in% crime_list) |> 
    group_by(year, crime_category, crime_count) |> 
    summarise(
      
    ) |> 
    mutate(
      year = str_remove(year,"x"),
      year = str_replace(year,"_","/")
    )
    
}

filter_provincial: This function is an extension of the previous function. The only difference is that the input dataframe has been filtered for provincial crime statistics.

Code
filter_df_provincial <- function(df, crime_list){
  df |> 
    filter(crime_category%in% crime_list) |> 
    group_by(year, station, crime_category, crime_count) |> 
    summarise(
      
    ) |> 
    mutate(
      year = str_remove(year,"x"),
      year = str_replace(year,"_","/")
    )
    
}

correlation_df: This functions creates a dataframe to be used to calculate the correlation between crimes and the chosen world bank indicators. The function has two input dataframes:

crime_df_national: dataframe containing the crime counts for each category on a national level.

wb_indicators_df: dataframe with world bank indicators used in this study.

Code
correlation_df <- function (crime_df_national, wb_indicators_df){
  # convert national df to wide format
  crime_df_national |> 
   pivot_wider(
     names_from = crime_category,
     values_from = crime_count
   ) |> 
   mutate(
     year = substring(year,1,4),
     year = parse_double(year)
   ) |> 
  # join crime_df_national with wb_indicators by year
    inner_join(
      wb_indicators_df,
      by="year"
    )
}

provincial_facet: This function creates a facet_wrap plot based on the 9 provinces in the country. The function is used to view the trend of each type of or grouping of crime(s). The function has two inputs:

  • df: an input dataframe

  • plot_title: plot title for the facet_wrap plot.

Code
provincial_facet <- function(df,plot_title) {
  ggplot(
    df,
    aes(
      x = year,
      y = crime_count,
      group = crime_category,
      color = crime_category
    )
  ) +
    geom_line() +
    geom_point()+
    labs(
      title = plot_title,
      x = "Year",
      y = "Number of observations"
    )+ 
    theme(
      plot.margin = margin(1,1,1,1,"cm"),
      axis.text.x = element_text(hjust=1, size=6,angle=45),
      legend.position = "bottom",
      legend.key.size = unit(0.05,"cm")) +
    guides(
      colour=guide_legend(ncol=1)
    )+
    facet_wrap(~station)
}

Station: This function is used to generate the top N stations that have the highest number of reported cases for a specific crime.

  • df: dataframe of South African crimes

  • crime_filter: filters the dataframe for the crime of interest

  • crime_title: title for the output table

  • rank: get the top rank results in the table

Code
station_crime_rank <- function(df,crime_filter,crime_title, rank){
  crime_station_df <- df |> 
    filter(crime_category %in% crime_filter) |> 
    group_by(
      station, province, district
    ) |> 
    summarise(
      crime_count = sum(crime_count)
    ) |> 
    arrange(
      desc(crime_count)
      ) |> 
    ungroup()
  
  crime_station_df <- crime_station_df |>
    mutate(
      Rank = row_number(),
      .before=1
    )
  crime_station_df_rank <- crime_station_df[1:rank, ] |> 
    gt() |> 
    tab_header(
      title = sprintf("Top %s Stations for %s", rank, crime_title),
      subtitle = "Data from 2013 to 2023"
    ) |> 
    cols_label(
      station="Station",
      province="Province",
      district="District"
    )

  return(crime_station_df_rank)
}

2.4 Import Datasets

Import the SAPS Annual Statistics raw csv file.

Code
# read in the SAPS Crime dataset
df_crime_sa = read_csv(here::here("data/raw/2022_2023 _annual_stats_raw.csv"))
#read_csv("../data/raw/2022_2023 _annual_stats_raw.csv")
# show first five observations
head(df_crime_sa)
# A tibble: 6 × 47
  Crime_Category National contribution\npl…¹ Crime_Category Provi…² `Comp level`
  <chr>                                      <chr>                  <chr>       
1 Murder Station 524                         Eastern Cape Murder S… Station     
2 Attempted murder Station 687               Eastern Cape Attempte… Station     
3 Robbery with aggravating circumstances St… Eastern Cape Robbery … Station     
4 Common robbery Station 1075                Eastern Cape Common r… Station     
5 Rape Station 672                           Eastern Cape Rape Sta… Station     
6 Sexual assault Station 802                 Eastern Cape Sexual a… Station     
# ℹ abbreviated names: ¹​`Crime_Category National contribution\nplacement`,
#   ²​`Crime_Category Provincial contribution\nplacement`
# ℹ 44 more variables: `Station Crime_Category` <chr>, Station <chr>,
#   District <chr>, Province <chr>, Crime_Category <chr>, Code <chr>,
#   `2013-2014` <dbl>, `2014-2015` <dbl>, `2015-2016` <dbl>, `2016-2017` <dbl>,
#   `2017-2018` <dbl>, `2018-2019` <dbl>, `2019-2020` <dbl>, `2020-2021` <dbl>,
#   `2021-2022` <dbl>, `2022-2023` <dbl>, …

Import the csv file containing general information (population, land size, density) about South African provinces.`

Code
# read in SA_info_dataset
za_df = read_csv(here::here("data/raw/South_Africa_provinces.csv"))
# show first five observations
#head(za_df)

Import the following World Bank datasets:

  • Gross domestic product per capita (1960 - 2023)

  • Unemployment (% of total labour force) (1960 - 2023)

  • Population (1960 - 2023)

Code
# import World Bank GDP Per Capita
wb_gdp = read_csv(here::here("data/raw/World_bank_GDP_Per_Capita.csv"))

# show first 5 observations
#head(wb_gdp)
Code
# import unemployment (% total labor force)
wb_uem = read_csv(here::here("data/raw/World_bank_unemployment_total_work_force.csv"))

# show first 5 observations
#head(wb_uem)
Code
# import population stats
wb_pop = read_csv(here::here("data/raw/World_Bank_Population_total.csv"))

# show first 5 observations
#head(wb_pop)

2.5 Data Processing

SAPS Raw

Code
# use the clean_names function to convert variable names to snake_case convention.
df_crime_sa_clean <- df_crime_sa |> 
  clean_names()
Code
# select relevant columns and remove columns with no information (NA in each row)

df_crime_sa_clean <- df_crime_sa_clean |>
  select(crime_category_national_contribution_placement:count_offence_group)
# further cleaning of empty columns
df_crime_sa_clean <- subset(df_crime_sa_clean, select = -c(crime_category_national_contribution_placement,crime_category_provincial_contribution_placement, station_crime_category,code,national_contribution_placement,national_count_diff_placement,provincial_contribution_placement, provincial_count_diff_placement, count_direction))
Code
# show first 5 observations
head(df_crime_sa_clean)

National

Code
# filter the crime dataset for observations where the comp_level is equal to National
df_crime_sa_national <- df_crime_sa_clean |>
  filter(comp_level=="National") |> 
  # select(crime_category:count_offence_group) |> 
  # select(!provincial_contribution_placement) |> 
  pivot_longer(
    cols = x2013_2014:x2022_2023,
    names_to = "year",
    values_to = "crime_count"
  )

# show first 5 observations
#head(df_crime_sa_national)

Provincial

Code
# filter the crime dataset for observations where the comp_level is equal to provincial
df_crime_sa_provincial <- df_crime_sa_clean |>
  filter(comp_level=="Province") |> 
  # select(crime_category:count_offence_group) |> 
  # select(!provincial_contribution_placement) |> 
  pivot_longer(
    cols = x2013_2014:x2022_2023,
    names_to = "year",
    values_to = "crime_count"
  )

# show first 5 observations
#head(df_crime_sa_provincial)

Station

Code
# filter the crime dataset for observations where the comp_level is equal to station
df_crime_sa_station <- df_crime_sa_clean |> 
  filter(comp_level=="Station") |> 
  pivot_longer(
    cols = x2013_2014:x2022_2023,
    names_to = "year",
    values_to = "crime_count"
  )

# show first 5 observations
#head(df_crime_sa_station)

World Bank Datasets

The data sets are all in a wide format, the preprocessing done will be to transform them to a long format and convert the values in the year column to numbers.

Code
# GDP per capita
za_gdp <- wb_gdp |> 
  filter(`Country Code` == "ZAF") |> 
  pivot_longer(
    cols = `1960`:`2022`,
    names_to = "year",
    values_to = "gdp_per_capita"
  ) |> 
  mutate(
    year = parse_number(year)
  )
Code
# unemployment (%total labour force)
za_uem <- wb_uem |> 
  filter(`Country Code`=="ZAF") |> 
  pivot_longer(
    cols = `1960`:`2022`,
    names_to = "year",
    values_to = "unemployment",
    values_drop_na = TRUE
  ) |> 
  mutate(
    year=parse_number(year)
  )
Code
# population stats
za_pop <- wb_pop |> 
  filter(`Country Code` == "ZAF") |> 
  pivot_longer(
    cols= `1960`:`2022`,
    names_to = "year",
    values_to = "population",
    values_drop_na = TRUE
  ) |> 
  mutate(
    year=parse_number(year)
  )

Join the World Bank data sets

Code
# join all the world bank dataset into one by year
za_joined <- inner_join(
  za_pop,
  za_gdp,
  by="year"
) |>
  inner_join(
    za_uem,
    by="year"
  ) |> 
  select(
    year,
    population,
    gdp_per_capita,
    unemployment
  )

2.6 Save processed files

SAPS Clean

Code
## save the df_crime_sa_clean to processed folder
write_csv(df_crime_sa_clean,here::here("data/processed/df_crime_clean.csv"))

SAPS National

Code
# save the df_crime_sa_national to processed folder
# write_csv(df_crime_sa_national,  here::here("data/processed/df_crime_sa_national.csv"))

SAPS Provincial

Code
# save the df_crime_sa_provincial
# write_csv(df_crime_sa_provincial, here::here("data/processed/df_crime_sa_provincial.csv"))

SAPS Station

Code
# save the df_crime_sa_station
# write_csv(df_crime_sa_station, here::here("data/processed/df_crime_sa_station.csv"))

World Bank Datasets

Code
# save the za_gdp to processed folder
write_csv(za_gdp,here::here("data/processed/ZAF_GDP_Per_Capita_19602022.csv"))
Code
# save the za_uem to the processed folder
write_csv(za_uem, here::here("data/processed/ZAF_UEM_19602022.csv"))
Code
# save the za_pop to the processed folder
write_csv(za_pop, here::here("data/processed/ZAF_POP_19602022.csv"))

2.7 Overview of South Africa

In this section, an overview of South Africa is presented - it serves as a pre-context to the crime statistics that will follow. First, the population density for each province is presented, and then we present several economic factors from the World Bank.

Plot South African population growth

Code
# ZA population
ggplot(za_pop,
       aes(
         x=year,
         y=population
       ))+
  geom_point()+
  geom_line()+
  geom_smooth(method = "lm")+
  ggtitle("Population growth of ZAF between 1960 - 2022")
Figure 1: South African population growth between 1960 and 2023.

Plot South African GDP per capita growth

Code
ggplot(za_gdp,
       aes(
         x=year,
         y=gdp_per_capita
       ))+
  geom_point()+
  geom_line()+
  geom_smooth(method = "lm")+
  labs (
    title = "South Africa GDP per capita between 1960 and 2023",
    x = "Year",
    y = "GDP per capita") +
  theme(legend.position = "bottom",
        legend.key.size = unit(0.15,"cm"))
Figure 2: South African GDP per capita between 1960 and 2023.

Plot South African unemployment growth

Code
ggplot(za_uem,
       aes(
         x=year,
         y=unemployment
       ))+
  geom_point()+
  geom_line()+
  geom_smooth(method = "lm")+
  labs (
    title = "South Africa Unemployment (%total labour force) between 1992 and 2023",
    x = "Year",
    y = "Unemployment (%total labour force") +
  theme(legend.position = "bottom",
        legend.key.size = unit(0.15,"cm"))
Figure 3: South African unemployment (%total labour force) between 1992 and 2023.

2.7.1 Provincial Composition of Crimes in the Country

In the previous section, we looked at how population, unemployment and GDP has changed throughout the years in South Africa. The reason was to provide some context to some of the crime statistics we shall see later on. We do not make any inferences as to the cause of the state of crimes just merely to see correlations between population growth, unemployment, and wealth production and state of crime in the country. South Africa has nine provinces are the Eastern Cape, the Free State, Gauteng, KwaZulu-Natal, Limpopo, Mpumalanga, the Northern Cape, North West, and the Western Cape.

The map of South Africa’s nine provinces. (source)

There is a vast size difference between the provinces, from the small and populated economic hub of Gauteng to the large and empty North West.

The land size of each South African province. (source)
Code
# transform data to sf object
za_sf = st_as_sf(za_df, coords  = c("long", "lat"))
ggplot(za_sf) +
  geom_sf(aes(col=density,
              size=population)
          ) +
  labs (
    title = "South Africa Population and Density",
    x = "Longitude",
    y = "Lattitude") 

Code
#+
#  theme(legend.position = "bottom",
#        legend.key.size = unit(0.15,"cm"))
# ggplot(za_df,
#        aes(x=population,
#            y=area,
#            size = density,
#            color=province) 
#        ) +
#   geom_point(alpha=0.7)+   
#   scale_size(range =c(.1,24),
#              name = "Population density")

Gauteng is the most densely populated province with the smallest land size and largest population of all the provinces. It is considered the economic hub of the country with a high rate of migration for better economic opportunities. The two major cities are Pretoria, the executive capital of the country, and Johannesburg, the financial hub. In 2016, Gauteng contributed 33.8% of South Africa’s gross domestic product and around 5% of the GDP of Africa (Alexander 2023). KwaZulu-Natal follows is the second most densely populated province, it has the biggest port in Durban, and contributed to 16% of the GDP in 2016. Western Cape, is the third major province in terms of density and economic contribution to South Africa. These three provinces are reported to contribute around two-thirds to the total economy of South Africa.

3 Results

The SAPS releases an annual crime report based on crime statistics, in which they focus on 21 priority crimes which are grouped into two main categories:

  • 17 community-reported serious crimes

  • Crimes detected as a result of police action

3.1 National Crime Trend

In this section, we will look at the crime trends on a national level across selected crime categories over a 10 year period. The dataset will be filtered for observations were the comp_level is national.

Code
#

3.1.1 Contact Crimes (Crimes Against The Person)

Contact crimes involves crimes where victims are targets of violence or cases where victims are near property that are target by criminals and are subjected to violence or the threats of violence.

The crimes included in this grouping are: Murder, Sexual offences, Attempted murder, Assault with the intention to inflict grievous bodily harm, Common assault, Common robbery, and Robbery with aggravating circumstances.

Two of the crime groupings can be further subdivided into other crimes:

  1. Sexual Offences

    • Rape

    • Sexual Assault

    • Attempted sexual offences

    • Contact sexual assault

  2. Robbery with aggravating circumstances

    • Carjacking Robbery at Non-residential premises

    • Robbery at residential premises

    • Robbery of cash in transit

    • Truck Hijacking

Code
# create contact_crimes list
contact_crimes_list <- c("Murder", "Sexual offences", "Attempted murder", "Assault with the intent to inflict grievous bodily harm", "Common assault", "Common robbery", "Robbery with aggravating circumstances")

# create contact crimes dataframe
contact_crimes_national <- filter_df(df_crime_sa_national, contact_crimes_list)
# view contact_crimes_national
head(contact_crimes_national)
# A tibble: 6 × 3
# Groups:   year, crime_category [6]
  year      crime_category                                          crime_count
  <chr>     <chr>                                                         <dbl>
1 2013/2014 Assault with the intent to inflict grievous bodily harm      182333
2 2013/2014 Attempted murder                                              16989
3 2013/2014 Common assault                                               166081
4 2013/2014 Common robbery                                                53505
5 2013/2014 Murder                                                        17023
6 2013/2014 Robbery with aggravating circumstances                       118963
Code
ggplot(data = contact_crimes_national,
       aes(
         x = year,
         y = crime_count,
         group = crime_category,
         color = crime_category
       ))+
  geom_line()+
  labs (
    title = "National Contact Crime between 2013 and 2023",
    x = "Year",
    y = "Number of Observations",
    colour="Crime Category"

  ) +
  geom_label(aes(
    label = crime_count
    #,colour = crime_category
  ),
  label.size = 0.1) +
  theme(legend.position = "bottom") +
  guides(colour = guide_legend(ncol = 1))
A line plot of national contact crime trend in South Africa between 2013 and 2023.
Figure 4: National contact crime trend between 2013 and 2023.
Code
# create contact correlation - round to 1 decimal
contact_wb_corr <- round(cor(correlation_df(contact_crimes_national, za_joined)),1)

#-----------calculate p values and marking insignificant corr values------------
# calculate p-values
p_contact <- cor_pmat(correlation_df(contact_crimes_national, za_joined))

# apply ggcorrplot 
ggcorrplot(contact_wb_corr,
           hc.order=TRUE,
           type="lower",
           p.mat = p_contact,
           title="Correlation between ZAF indicators and contact crimes",
           legend.title = "Pearson\n Corr",
           lab=TRUE,
           lab_size=2,
           ggtheme = theme_grey
           )+
  scale_x_discrete(labels = label_wrap(25))+
  theme(
    axis.text.x = element_text(size=10)
  )

Code
contact_crimes_national_wide <- contact_crimes_national |> 
   pivot_wider(
     names_from = crime_category,
     values_from = crime_count
   ) |> 
   mutate(
     year = substring(year,1,4)
   )
  
 
# contact_crimes_national_wide |> 
#   gt()

According to the stats and as presented in Figure 4, common assault, assault with the intent to inflict grievous bodily harm, and robbery with aggravating circumstances have been the most frequent contact crimes in South Africa in the past 10 years.

3.1.1.1 Sexual Offences

We shall look at the occurrence of sexual offences in the country over the past 10 years.

Code
# create a list of offences that compose of sexual offences
sexual_offences_list <- c("Rape","Sexual assault","Attempted sexual offences","Contact sexual offences")

# filter out these offences from the national crime data frame
sexual_offences_national <- filter_df(df_crime_sa_national, sexual_offences_list)
Code
ggplot(data = sexual_offences_national,
       aes(
         x = year,
         y = crime_count,
         group = crime_category,
         color = crime_category
       ))+
  geom_line()+
  labs (
    title = "National Sexual Offences between 2013 and 2023",
    x = "Year",
    y = "Number of Observations"

  ) +
  geom_label(aes(
    label = crime_count,
    colour = crime_category
  ),
  label.size = 0.1) +
  theme(legend.position = "bottom",
        legend.key.size = unit(0.15,"cm"))+
  guides(colour = guide_legend(ncol = 1))
A line plot on a polar axis
Figure 5: National sexual offences crime trend between 2013 and 2023.

In Figure 5, rape has consistently been the most frequent sexual offence in the past 10 years. The number of rape incidents has been 5 times greater than the other offences combined during this 10 year period. South Africa is among the countries with the highest rape cases in the world - higher than countries at war. There were 42780 cases reported in 2022/2023, which equates to 177 incidents per day. Rape is a systemic and endemic problem in South Africa.

3.1.1.2 Aggravated Robbery

Code
# create a list of some of the subcategories of aggravated robbery
robbery_agg_list <- c("Carjacking","Robbery at residential premises","Robbery at non-residential premises" )

# use the list to filter national crime dataframe
robbery_agg_national <- filter_df(df_crime_sa_national, robbery_agg_list)

ggplot(data = robbery_agg_national,
       aes(
         x = year,
         y = crime_count,
         group = crime_category,
         color = crime_category
       ))+
  geom_line()+
  labs (
    title = "National Aggrevated Robbery between 2013 and 2023",
    x = "Year",
    y = "Number of Observations"

  ) +
  geom_label(aes(
    label = crime_count,
    colour = crime_category
  ),
  label.size = 0.1) +
  theme(legend.position = "bottom",
        legend.key.size = unit(0.15,"cm"))+
  guides(colour = guide_legend(ncol = 1))
A line plot on a polar axis
Figure 6: National Aggrebated Robbery trend between 2013 and 2023.

Figure Figure 6 shows that crimes in the aggravated robbery category have all increased during this 10 year period. Robbery at residential premises has topped the list out of these three crimes. However, carjacking has steadily increased in this time period and based on the trend, is expected to surpass robbery at residential premises.

3.1.4 Other Serious Crimes

These are serious crimes which have not been included in the categories above.

  • All Theft not mentioned elsewhere

  • Commercial crime

  • Shoplifting

Code
# create a list of the other serious crimes
serious_crimes_list <- c("All theft not mentioned elsewhere", "Commercial crime", "Shoplifting")

# create a dataframe for other serious crimes
serious_crimes_national <- filter_df(df_crime_sa_national, serious_crimes_list)

# plot the national trend of national serious crimes
ggplot(data = serious_crimes_national,
       aes(
         x = year,
         y = crime_count,
         group = crime_category,
         color = crime_category
       ))+
  geom_line()+
  labs (
    title = "National Other Serious crimes between 2013 and 2023",
    x = "Year",
    y = "Number of Observations"

  ) +
  geom_label(aes(
    label = crime_count,
    colour = crime_category
  ),
  label.size = 0.1) +
  theme(legend.position = "bottom",
        legend.key.size = unit(0.15,"cm"))
A line plot on a polar axis
Figure 9: National trend of other serious crimes trend between 2013 and 2023.

Theft is the most frequent crime in the other serious crimes category (Figure Figure 9).

3.1.5 Crimes Detected as a Result of Police Action

These are crimes mostly which are not reported to police, and are mostly dependent on the deployment of law enforcement and intelligence personnel. These crimes are recorded after the arrest of suspects connected to the following crimes.

  • Illegal possession of firearms and ammunition

  • Drug-related crimes

  • Driving under the influence of alcohol and/or drugs

  • Sexual offences detected as a result of police action

Code
# create a list of the crimes detected as a result of police action
police_detected_list <- c("Illegal possession of firearms and ammunition", "Drug-related crime", "Driving under the influence of alcohol or drugs", "Sexual offences detected as a result of police action")

# create a dataframe for crimes detected as a result of police action
police_detected_crimes_national <- filter_df(df_crime_sa_national, police_detected_list)

# plot the national trend of crimes detected as a result of police action
ggplot(data = police_detected_crimes_national,
       aes(
         x = year,
         y = crime_count,
         group = crime_category,
         color = crime_category
       ))+
  geom_line()+
  labs (
    title = "National trend of crimes detected as a result of police action between 2013 and 2023",
    x = "Year",
    y = "Number of Observations"

  ) +
  geom_label(aes(
    label = crime_count,
    colour = crime_category
  ),
  label.size = 0.1) +
  theme(legend.position = "bottom",
        legend.key.size = unit(0.15,"cm"))+
  guides(colour = guide_legend(ncol = 1))
A line plot on a polar axis
Figure 10: National trend of crimes detected as a result of police action between 2013 and 2023.

Figure Figure 10 shows the number of cases detected as a result of SAPS deployment. Therefore, making sense of this data visualization is interesting as increases and decreases can not be interpreted in the same as the previous figures. A decrease can be viewed as a negative because this means SAPS deployment and an increase can be viewed as more effective SAPS deployment.

3.2 Provincial Crime Trend

In this section, we will look at the crime trends on a provincial level across selected crime categories over a 10 year period. The dataset will be filtered for observations were the comp_level is Province. This section looks at how each of the 9 provinces contribute to the national numbers.

3.2.1 Contact Crimes

Code
# create contact crimes dataframe
contact_crimes_provincial <- filter_df_provincial(df_crime_sa_provincial, contact_crimes_list)
# create contact crimes facet plot
provincial_facet(contact_crimes_provincial, "Contact crime trend between 2013 and 2023 by Province")
Figure 11: The trend of contact crimes in each province between 2013 and 2023.

In Figure Figure 11, we see that the three most densely populated provinces have the higher number of cases for robbery with aggravating circumstances, assault with intent to inflict grievous bodily harm, and common assault. In Free State, Limpopo, Mpumalanga, North West, and Northern Cape, contact crime trend has stayed relatively constant during this period of interest. However, the trend of assault with the intention to inflict grievous bodily harm in Eastern Cape matches that of the big three provinces mentioned first above.

3.2.1.1 Sexual Offences

Code
# create sexual offences dataframe
sexual_offences_provincial <- filter_df_provincial(df_crime_sa_provincial, sexual_offences_list)
# create sexual offences facet plot
provincial_facet(sexual_offences_provincial, "Sexual Offences Trend between 2013 and 2023 by Province")
Figure 12: The trend of sexual offences crimes in each province between 2013 and 2023.

Figure Figure 12, highlights South Africa’s challenge with rape. Rape has the highest rates during this time period in all provinces. In each province, we see a drop in this crime between 2019/2020 and 2020/2021. At first glance, the drop could be correlated in the hard-lockdown that occurred due to COVID-19. Eastern Cape, Gauteng, and Kwazulu-Natal are the three provinces with the highest counts of rape during this period.

3.2.1.2 Aggravated Robbery

Code
# create aggrevated robbery dataframe
robbery_agg_provincial <- filter_df_provincial(df_crime_sa_provincial,robbery_agg_list )

# create aggrevated robbery facet plot
provincial_facet(robbery_agg_provincial,
                 "Aggrevated Robbery Trend between 2013 and 2023 by Province")
Figure 13: The trend of aggravated robbery in each province between 2013 and 2023.

Figure Figure 13 shows the trend of aggravated robbery crimes - carjacking and robbery at non-residential and residential premises. Gauteng has the highest numbers for each crime in this category during this period. We also notice that the increase in carjacking, which was mentioned in Figure 6, predominantly occurs in Gauteng. Northern Cape, has the lowest number of aggravated robbery crimes during this period.

3.2.4 Other Serious Crimes

Code
# create provincial dataframe for other serious crimes
serious_crimes_provincial <- filter_df_provincial(df_crime_sa_provincial, serious_crimes_list)

# create other serious crimes facet wrap
provincial_facet(serious_crimes_provincial, "Other Serious Crimes Provincial Trend between 2013 and 2023")
Figure 16: The trend of other serious crimes in each province between 2013 and 2023.

Figure Figure 16 shows the crime trend of crimes - all theft not mentioned elsewhere, commercial crime, and shoplifting. Theft is the most frequent crime in this category during this period with Gauteng and Western Cape having the highest numbers.

3.2.5 Crimes Detected as a Result of Police action

Code
# create a provincial dataframe for the crimes detected as a result of police action
police_detected_provincial <- filter_df_provincial(df_crime_sa_provincial, police_detected_list)

# create a facet plot for the provincial 
provincial_facet(police_detected_provincial, "Provincial Trend of Crimes Detected As A Result of Police Action \n Between 2013 and 2023")
Figure 17: The trend of crimes detected as a result of police action in each province between 2013 and 2023.

Figure Figure 17 shows the crime trend of crimes - driving under the influence, drug-related crimes, illegal possession of firearms and ammunition, and sexual offences detected as a result of police action. The crimes detected as a result of police action has stayed relatively constant in all the provinces besides Western Cape, Gauteng, and kwaZulu-Natal. We see a reduction in police detecting drug-related crimes in these provinces from 2017/2018.

3.3 Station Crime Trend

The station level allows us to see which areas (police station) have the highest reported crimes. We can look at it per province or can compile the top 10 stations and see which province occurs the most.

3.3.1 Contact Crimes

Code
# create contact crimes dataframe

contact_station10 <- station_crime_rank(df_crime_sa_station,contact_crimes_list,"Contact Crimes", 10)
contact_station10
Table 1: The top ranking stations in South Africa for contact crimes.
Top 10 Stations for Contact Crimes
Data from 2013 to 2023
Rank Station Province District crime_count
1 JHB Central Gauteng Johannesburg District 46341
2 Mitchells Plain Western Cape City of Cape Town District 42671
3 Nyanga Western Cape City of Cape Town District 41268
4 Hillbrow Gauteng Johannesburg District 39617
5 Khayelitsha Western Cape City of Cape Town District 34011
6 Umlazi KwaZulu-Natal eThekwini District 33747
7 Temba Gauteng Tshwane District 31969
8 Inanda KwaZulu-Natal eThekwini District 30858
9 Kagiso Gauteng West Rand District 30017
10 Alexandra Gauteng Johannesburg District 29998

Table Table 1 shows the top 10 stations with the highest amount of contact crime cases in South Africa between 2013 and 2023. We can see that stations are all from Gauteng, Western Cape, or kwaZulu-Natal. The stations are all based in under-resourced neighbourhoods (townships) which are densely populated. The City of Cape Town District and eThekwini District are the only districts from Western Cape and kwaZulu-Natal, respectively. In Gauteng, Johannesburg District and Tshwane (Pretoria) District make the top 10.

We now look at selected crimes in the contact crimes category.

3.3.1.1 Murder

Code
murder_station10 <- station_crime_rank(df_crime_sa_station,"Murder","Murder", 10)
murder_station10
Table 2: The top ranking stations in South Africa for Murder.
Top 10 Stations for Murder
Data from 2013 to 2023
Rank Station Province District crime_count
1 Nyanga Western Cape City of Cape Town District 2549
2 Inanda KwaZulu-Natal eThekwini District 2228
3 Delft Western Cape City of Cape Town District 2109
4 Umlazi KwaZulu-Natal eThekwini District 2107
5 Khayelitsha Western Cape City of Cape Town District 1925
6 Harare Western Cape City of Cape Town District 1725
7 Kraaifontein Western Cape City of Cape Town District 1664
8 Mfuleni Western Cape City of Cape Town District 1643
9 Gugulethu Western Cape City of Cape Town District 1603
10 Plessislaer KwaZulu-Natal Umgungundlovu District 1569

Table Table 2 shows the stations which had the highest number of reported cases of murder between 2013 and 2023. The City of Cape Town District has been called the murder capital of South Africa. There 7 stations from this district in the top 10 and this is due to the high level of poverty and gangsterism in these under-resourced communities. The remaining three are from kwaZulu-Natal (eThwekini District) with Inanda second on the list.

3.3.1.2 Sexual Offences

Code
sexoffence_station10 <- station_crime_rank(df_crime_sa_station,"Sexual offences","Sexual Offences",10)
sexoffence_station10
Table 3: The stations in South Africa with the most cases for sexual offences.
Top 10 Stations for Sexual Offences
Data from 2013 to 2023
Rank Station Province District crime_count
1 Inanda KwaZulu-Natal eThekwini District 3397
2 Umlazi KwaZulu-Natal eThekwini District 3004
3 Nyanga Western Cape City of Cape Town District 2771
4 Thohoyandou Limpopo Vhembe District 2650
5 Delft Western Cape City of Cape Town District 2591
6 Lusikisiki Eastern Cape OR Tambo District 2279
7 Mthatha Eastern Cape OR Tambo District 2269
8 Plessislaer KwaZulu-Natal Umgungundlovu District 2268
9 Temba Gauteng Tshwane District 2268
10 Empangeni KwaZulu-Natal King Cetshwayo District 2246

Table Table 3 shows the stations that had the highest number of reported cases for sexual offences between 2013 and 2023. Inanda, kwaZulu-Natal has the highest number of cases for sexual offences in this period. Eastern Cape (Lusikisiki and Mthatha) and Limpopo (Thohoyandou) , which have not appeared in the previous tables are included in the top 10.

3.3.1.2.1 Robbery with aggravating circumstances
Code
rac_station10 <- station_crime_rank(df_crime_sa_station,"Robbery with aggravating circumstances","Robbery With Aggravating Circumstances",10)
rac_station10
Table 4: The stations in South Africa with the most cases for robbery with agrravated circumstances.
Top 10 Stations for Robbery With Aggravating Circumstances
Data from 2013 to 2023
Rank Station Province District crime_count
1 JHB Central Gauteng Johannesburg District 15785
2 Nyanga Western Cape City of Cape Town District 14199
3 Khayelitsha Western Cape City of Cape Town District 12804
4 Pinetown KwaZulu-Natal eThekwini District 10549
5 Hillbrow Gauteng Johannesburg District 10468
6 Durban Central KwaZulu-Natal eThekwini District 10401
7 Honeydew Gauteng Johannesburg District 9759
8 Mitchells Plain Western Cape City of Cape Town District 9157
9 Jeppe Gauteng Johannesburg District 8663
10 Tembisa Gauteng Ekurhuleni District 8246

Table Table 4 shows the stations that had the highest number of reported cases for robbery with aggravation circumstances between 2013 and 2023. Johannesburg Central Station had the highest - 15785, in this 10 year period. Johannesburg is in the most densily populated province, Gauteng, and has an increasing population growth due to migrant workers looking for better opportunities in the economic hub of South Africa. The three most densely populated provinces in the country make up this table.

3.3.1.3 Rape

Code
rape_station10 <- station_crime_rank(df_crime_sa_station,"Rape","Rape",10)
rape_station10
Table 5: The stations in South Africa with the most cases for rape offences.
Top 10 Stations for Rape
Data from 2013 to 2023
Rank Station Province District crime_count
1 Inanda KwaZulu-Natal eThekwini District 2942
2 Umlazi KwaZulu-Natal eThekwini District 2626
3 Thohoyandou Limpopo Vhembe District 2373
4 Lusikisiki Eastern Cape OR Tambo District 2074
5 Mthatha Eastern Cape OR Tambo District 2040
6 Nyanga Western Cape City of Cape Town District 2034
7 Delft Western Cape City of Cape Town District 2023
8 Plessislaer KwaZulu-Natal Umgungundlovu District 1969
9 Empangeni KwaZulu-Natal King Cetshwayo District 1911
10 Temba Gauteng Tshwane District 1876

Table Table 5 shows the stations with the highest number of reported rape cases in the country between 2013 and 2023. The stations in this table are similar to that of Table Table 3.

3.3.1.4 Attempted Sexual Offences

Code
att_sexual_offences_station10 <- station_crime_rank(df_crime_sa_station,"Attempted sexual offences","Attempted sexual offences",10)
att_sexual_offences_station10
Table 6: The stations in South Africa with the most cases for attempted sexual offences.
Top 10 Stations for Attempted sexual offences
Data from 2013 to 2023
Rank Station Province District crime_count
1 Mankweng Limpopo Capricorn District 182
2 Nyanga Western Cape City of Cape Town District 156
3 Mogwase North West Bojanala District 139
4 Galeshewe Northern Cape Frances Baard District 136
5 Harare Western Cape City of Cape Town District 129
6 Mmabatho North West Ngaka Modiri Molema District 127
7 Taung North West Dr Ruth Segomotsi Mompati District 126
8 Seshego Limpopo Capricorn District 125
9 Boitekong North West Bojanala District 117
10 Delft Western Cape City of Cape Town District 117

Table Table 6 shows the stations with the highest cases of attempted sexual offences in the country between 2013 and 2023. The entries in this table have not featured in the previous tables, and we see a station from Northern Cape in the top four.

3.3.3 Other Serious Crimes

Code
serious_crimes_station<- station_crime_rank(df_crime_sa_station,serious_crimes_list,"Other Serious Crimes",10)
serious_crimes_station
Table 11: The stations in South Africa with the most cases of other serious crimes.
Top 10 Stations for Other Serious Crimes
Data from 2013 to 2023
Rank Station Province District crime_count
1 Cape Town Central Western Cape City of Cape Town District 60987
2 Durban Central KwaZulu-Natal eThekwini District 41719
3 Park Road Free State Mangaung District 40355
4 JHB Central Gauteng Johannesburg District 39990
5 Mitchells Plain Western Cape City of Cape Town District 38427
6 Sandton Gauteng Johannesburg District 34950
7 Honeydew Gauteng Johannesburg District 31223
8 Midrand Gauteng Johannesburg District 30966
9 Pretoria Central Gauteng Tshwane District 30447
10 Brooklyn Gauteng Tshwane District 30072

3.3.4 Crimes Detected as a Result of Police Action

Code
police_action_station<- station_crime_rank(df_crime_sa_station,police_detected_list,"Police Action",10)
police_action_station
Table 12: The stations in South Africa with the most cases due to police action.
Top 10 Stations for Police Action
Data from 2013 to 2023
Rank Station Province District crime_count
1 Mitchells Plain Western Cape City of Cape Town District 48585
2 Durban Central KwaZulu-Natal eThekwini District 39735
3 Kraaifontein Western Cape City of Cape Town District 35183
4 Delft Western Cape City of Cape Town District 31131
5 Bishop Lavis Western Cape City of Cape Town District 24081
6 Cape Town Central Western Cape City of Cape Town District 24037
7 Atlantis Western Cape City of Cape Town District 23614
8 Manenberg Western Cape City of Cape Town District 23180
9 Lentegeur Western Cape City of Cape Town District 22098
10 Phoenix KwaZulu-Natal eThekwini District 21667
Code
# farm_murders
station_crime_rank(df_crime_sa_station,"farm","Police Action",10)
Top 10 Stations for Police Action
Data from 2013 to 2023
Rank Station Province District crime_count
NA NA NA NA NA
NA NA NA NA NA
NA NA NA NA NA
NA NA NA NA NA
NA NA NA NA NA
NA NA NA NA NA
NA NA NA NA NA
NA NA NA NA NA
NA NA NA NA NA
NA NA NA NA NA

4 Conclusion

In this project, the crime statistics released by the SAPS for 2022/2023 was analysed to determine the state of crime in the country. The following are the findings:

  • The trend of crime in the Republic of South Africa seems to be on the increase according to the crime statistics published by the South African Police Service.

  • There was a reduction in most crimes in the reported year of 2020/2021 - this could be attributed to the COVID-19 restrictions on movement. This would have to be investigated in another study.

  • The highest crime rates can be found in under-resourced areas where there is high unemployment and poverty levels.

  • The trend of contact crimes has been on the increase since 2020/2021.

  • The trend of carkacking in the country has increased by 103% between 2013 and 2023 - with Gauteng being the hub for this crime.

5 References

References

AKINOLA, Gbenga, and Abieyuwa Ohonba. 2023. “Youth Unemployment and Rising Crime Rate in South Africa: Does Governance Matter?”
Alexander, Mary. 2023. “The Nine Provinces of South Africa.” South Africa Gateway. https://southafrica-info.com/land/nine-provinces-south-africa/.
Bhorat, Haroon, Amy Thornton, Kirsten Van der Zee, et al. 2017. “Socio-Economic Determinants of Crime in South Africa: An Empirical Assessment.”
Brown, Kay V. 2001. “The Determinants of Crime in South Africa.” South African Journal of Economics 69 (2): 269–98.
Brown, Leanora, and Keva Hibbert. 2017. “The Effect of Crime on Foreign Direct Investment: A Multi-Country Panel Data Analysis.” The Journal of Developing Areas 51 (1): 295–307.
Glaser, Clive. 2008. “Violent Crime in South Africa: Historical Perspectives.” South African Historical Journal 60 (3): 334–52.

Reuse