07-activity

Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see https://quarto.org.

Running Code

When you click the Render button a document will be generated that includes both content and the output of embedded code. You can embed code like this:

# Libraries
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.2     ✔ tibble    3.2.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.4     
── 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(lubridate)
library(janitor)

Attaching package: 'janitor'

The following objects are masked from 'package:stats':

    chisq.test, fisher.test
library(knitr)

#Task_01
clean_crime_data <- function(df) {
  df <- janitor::clean_names(df)

  if ("offense_2_0" %in% names(df)) {
    df <- dplyr::rename(df, offense = offense_2_0)
  }

  df |>
    mutate(
      arrest_time = lubridate::parse_date_time(
        arrest_time,
        orders = c("Y-m-d HMS", "Y-m-d HM", "mdy HMS", "mdy HM", "mdy"),
        quiet  = TRUE
      ),
      report_name = as.factor(report_name)
    ) |>
    filter(!is.na(zone), neighborhood != "Outside City")
}
#Load_all_weeks
load_all_weeks <- function(dir = "07-activity-data", verbose = FALSE) {
  files <- list.files(
    path       = dir,
    pattern    = "^crime[-_ ]?week.*\\.csv$",
    full.names = TRUE,
    ignore.case = TRUE,
    recursive   = TRUE
  )

  if (length(files) == 0) {
    warning("No CSVs found in: ", normalizePath(dir, mustWork = FALSE))
    return(tibble())
  }
  if (verbose) message("Found ", length(files), " CSVs")

  purrr::map_dfr(
    files,
    \(f) {
      readr::read_csv(f, show_col_types = FALSE) |>
        clean_crime_data() |>
        mutate(
          source_file = basename(f),
          week        = readr::parse_number(source_file)
        )
    }
  )
}

#Task_03_Tidyup
data_dir <- "07-activity-data"          
crimes   <- load_all_weeks(data_dir)      
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `week = readr::parse_number(source_file)`.
Caused by warning:
! 3912 parsing failures.
row col expected           actual
  1  -- a number crime-week-0.csv
  2  -- a number crime-week-0.csv
  3  -- a number crime-week-0.csv
  4  -- a number crime-week-0.csv
  5  -- a number crime-week-0.csv
... ... ........ ................
See problems(...) for more details.
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `week = readr::parse_number(source_file)`.
Caused by warning:
! 524 parsing failures.
row col expected           actual
  1  -- a number crime-week-1.csv
  2  -- a number crime-week-1.csv
  3  -- a number crime-week-1.csv
  4  -- a number crime-week-1.csv
  5  -- a number crime-week-1.csv
... ... ........ ................
See problems(...) for more details.
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `week = readr::parse_number(source_file)`.
Caused by warning:
! 1373 parsing failures.
row col expected           actual
  1  -- a number crime-week-2.csv
  2  -- a number crime-week-2.csv
  3  -- a number crime-week-2.csv
  4  -- a number crime-week-2.csv
  5  -- a number crime-week-2.csv
... ... ........ ................
See problems(...) for more details.
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `week = readr::parse_number(source_file)`.
Caused by warning:
! 1221 parsing failures.
row col expected           actual
  1  -- a number crime-week-3.csv
  2  -- a number crime-week-3.csv
  3  -- a number crime-week-3.csv
  4  -- a number crime-week-3.csv
  5  -- a number crime-week-3.csv
... ... ........ ................
See problems(...) for more details.
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `week = readr::parse_number(source_file)`.
Caused by warning:
! 1054 parsing failures.
row col expected           actual
  1  -- a number crime-week-4.csv
  2  -- a number crime-week-4.csv
  3  -- a number crime-week-4.csv
  4  -- a number crime-week-4.csv
  5  -- a number crime-week-4.csv
... ... ........ ................
See problems(...) for more details.
if (nrow(crimes) == 0) {
  stop("No rows loaded. Check that the CSVs are in: ", data_dir)
}

crimes |>
  select(week, report_name, section, description,
         neighborhood, zone, arrest_time) |>
  slice_head(n = 20) |>
  kable(caption = "First 20 cleaned rows")
First 20 cleaned rows
week report_name section description neighborhood zone arrest_time
NA OFFENSE 2.0 4120 Identity Theft Golden Triangle/Civic Arena 2 2015-03-10 00:01:00
NA OFFENSE 2.0 9488 False Burglar Alarm Central Northside 1 2015-03-10 00:54:00
NA OFFENSE 2.0 29 Missing Juvenile Homewood South 5 2015-03-10 00:56:00
NA ARREST 3503 Criminal Trespass Central Oakland 4 2015-03-10 01:30:00
NA ARREST 3929(a)(1) Retail Theft; takes possession of carries away or transfers displayed merchandise Central Oakland 4 2015-03-10 01:30:00
NA ARREST 5505 Public Drunkenness Central Oakland 4 2015-03-10 01:30:00
NA OFFENSE 2.0 3921 Theft by Unlawful Taking or Disposition. Perry South 1 2015-03-10 01:38:00
NA OFFENSE 2.0 9488 False Burglar Alarm Perry South 1 2015-03-10 01:41:00
NA OFFENSE 2.0 3802(a)(1) DUI - General Impairment Beltzhoover 3 2015-03-10 01:46:00
NA OFFENSE 2.0 4706 Prohib. on Expend. for Emission Insp Prog.. Beltzhoover 3 2015-03-10 01:46:00
NA OFFENSE 2.0 4703 Operation of Vehicle without Official Certif. of Inspection Beltzhoover 3 2015-03-10 01:46:00
NA OFFENSE 2.0 3802(d)(2) DUI - Drug - Impaired Ability Beltzhoover 3 2015-03-10 01:46:00
NA ARREST 4706 Prohib. on Expend. for Emission Insp Prog.. Beltzhoover 3 2015-03-10 01:53:00
NA ARREST 4703 Operation of Vehicle without Official Certif. of Inspection Beltzhoover 3 2015-03-10 01:53:00
NA ARREST 3802(d)(2) DUI - Drug - Impaired Ability Beltzhoover 3 2015-03-10 01:53:00
NA ARREST 3802(a)(1) DUI - General Impairment Beltzhoover 3 2015-03-10 01:53:00
NA OFFENSE 2.0 5505 Public Drunkenness Brighton Heights 1 2015-03-10 01:57:00
NA OFFENSE 2.0 601.16 Public Urination And Defecation Brighton Heights 1 2015-03-10 01:57:00
NA OFFENSE 2.0 3309 Driving on Roadways Laned for Traffic. Golden Triangle/Civic Arena 2 2015-03-10 02:29:00
NA OFFENSE 2.0 3802(b) DUI - High Rate of Alchol - BAC >=.10% <.16% Golden Triangle/Civic Arena 2 2015-03-10 02:29:00
offense_table <- function(section_code, data = crimes, top_n = 25) {

  counts <- data |>
    filter(report_name == "OFFENSE", section == section_code) |>
    count(neighborhood, week, name = "n")

  if (nrow(counts) == 0) {
    return(kable(tibble(Note = paste("No rows for SECTION", section_code))))
  }

  top_neigh <- counts |>
    group_by(neighborhood) |>
    summarise(total = sum(n), .groups = "drop") |>
    slice_max(total, n = top_n) |>
    select(-total)

  tab <- top_neigh |>
    left_join(counts, by = "neighborhood") |>
    tidyr::pivot_wider(names_from = week, values_from = n, values_fill = 0) |>
    arrange(neighborhood)

  kable(
    tab,
    caption = paste(
      "SECTION", section_code, "— top",
      min(top_n, nrow(top_neigh)), "neighborhoods × week"
    )
  )
}
#Task_04_Tables
offense_tables <- function(section_codes, data = crimes, top_n = 25) {
  for (code in section_codes) {
    offense_table(code, data, top_n = top_n)
    cat("\n\n") 
  }
}

offense_tables(c("3701", "2701", "3304"), crimes, top_n = 25)

You can add options to executable code like this

[1] 4

The echo: false option disables the printing of code (only output is displayed).