Showing 1 of 9 files from the diff.
Newly tracked file
R/stop_and_search.R changed.
Other files ignored by Codecov

@@ -1,5 +1,217 @@
Loading
1 +
#' Find stop and search at street level
2 +
#'
3 +
#' Crimes at street-level; either within a 1 mile radius of a single point
4 +
#'     (`ukp_stop_search`), or within a custom area (`ukp_stop_search_poly`).
5 +
#'     The street-level crimes returned in the API are only an approximation of
6 +
#'     where the actual crimes occurred, they are not the exact locations. See
7 +
#'     the about page (<https://data.police.uk/about/#location-anonymisation>)
8 +
#'     for more information about location anonymisation. Note that crime
9 +
#'     levels may appear lower in Scotland, as only the British Transport
10 +
#'     Police provide this data.
11 +
#'
12 +
#' @param lat latitude of the requested crime area
13 +
#' @param lng, longitude of the requested crime area
14 +
#' @param poly_df dataframe containing the lat/lng pairs which define the
15 +
#'   boundary of the custom area. If a custom area contains more than 10,000
16 +
#'   crimes, the API will return a 503 status code. ukp_crime_poly converts the
17 +
#'   dataframe into lat/lng pairs, separated by colons:
18 +
#'   `lat`,`lng`:`lat`,`lng`:`lat`,`lng`. The first and last coordinates need
19 +
#'   not be the same — they will be joined by a straight line once the request
20 +
#'   is made.
21 +
#' @param date, Optional. (YYY-MM), limit results to a specific month. The
22 +
#'   latest month will be shown by default. e.g. date = "2013-01"
23 +
#' @param ... further arguments passed to or from other methods. For example,
24 +
#'   verbose option can be added with
25 +
#'   `ukp_api("call", config = httr::verbose())`. See more in `?httr::GET`
26 +
#'  documentation
27 +
#'   (<https://cran.r-project.org/web/packages/httr/>) and
28 +
#'   (<https://cran.r-project.org/web/packages/httr/vignettes/quickstart.html>).
29 +
#' @name ukp_stop_search
30 +
#'
31 +
#' @note The API will return a 400 status code in response to a GET request
32 +
#'   longer than 4094 characters. For submitting particularly complex poly
33 +
#'   parameters, consider using POST instead.
34 +
#'
35 +
#' @return a tibble with the columns:
36 +
#'   - type:	Whether this was a 'Person search', a 'Vehicle search', or a
37 +
#'     'Person and Vehicle search'
38 +
#'   - involved_person:	Whether a person was searched in this incident
39 +
#'     (derived from type; true if anything but 'Vehicle search')
40 +
#'   - datetime:	When the stop and search took place. Note that some forces
41 +
#'     only provide dates for their stop and searches, so you might see a
42 +
#'     disproportionate number of incidents occurring at midnight.
43 +
#'   - operation: (not always present in data)	Whether this stop and search
44 +
#'     was part of a policing operation
45 +
#'   - operation_name: (not always present in data) name of the operation this
46 +
#'     stop and search was part of
47 +
#'   - location:	Approximate location of the incident
48 +
#'   - latitude:	Latitude
49 +
#'   - longitude:	Longitude
50 +
#'   - street:	The approximate location of the incident
51 +
#'   - id:	Unique identifier for the location
52 +
#'   - name:	Human-readable summary of the location
53 +
#'   - gender:	Human-readable gender of the person stopped, if applicable
54 +
#'     and provided
55 +
#'   - age_range:	The age range of the person stopped at the time the stop
56 +
#'     occurred
57 +
#'   - self_defined_ethnicity:	The self-defined ethnicity of the person stopped
58 +
#'   - officer_defined_ethnicity:	The officer-defined ethnicity of the person
59 +
#'     stopped
60 +
#'   - legislation:	The power used to carry out the stop and search
61 +
#'   - object_of_search:	The reason the stop and search was carried out
62 +
#'   - outcome:	The outcome of the stop. false if nothing was found, an empty
63 +
#'     string if no outcome was provided.
64 +
#'   - outcome_linked_to_object_of_search:	Whether the outcome was related to
65 +
#'     the reason the stop and search was carried out, as a boolean value
66 +
#'     (or null if not provided)
67 +
#'   - removal_of_more_than_outer_clothing:	Whether the person searched had
68 +
#'     more than their outer clothing removed, as a boolean value (or null if
69 +
#'     not provided)
70 +
#' @note more documentation here:
71 +
#'   <https://data.police.uk/docs/method/stops-street/>
72 +
#'
73 +
#' @examples
74 +
#'
75 +
#' ukp_stop_search_data <- ukp_stop_search(lat = 52.629729,
76 +
#'                                         lng = -1.131592)
77 +
#'
78 +
#' head(ukp_stop_search_data)
79 +
#'
80 +
#' @export
81 +
ukp_stop_search <- function(lat,
82 +
                            lng,
83 +
                            date = NULL,
84 +
                            ...){
85 +
86 +
  # if date is used
87 +
  if (is.null(date) == FALSE) {
88 +
89 +
    api_string <- glue::glue("api/stops-street?lat={lat}&lng={lng}&date={date}")
90 +
91 +
    # else if no date is specified
92 +
  } else if (is.null(date) == TRUE) {
93 +
94 +
    api_string <- glue::glue("api/stops-street?lat={lat}&lng={lng}")
95 +
96 +
  }
97 +
98 +
  result <- ukp_api(api_string)
99 +
  extract_result <- purrr::map_dfr(.x = result$content,
100 +
                                   .f = ukp_crime_unlist)
101 +
102 +
103 +
  # rename the data
104 +
  extract_result <- dplyr::rename(
105 +
    extract_result,
106 +
    lat = location.latitude,
107 +
    long = location.longitude,
108 +
    street_id = location.street.id,
109 +
    street_name = location.street.name,
110 +
    outcome_object_id = outcome_object.id,
111 +
    outcome_object_name = outcome_object.name,
112 +
  )
113 +
114 +
  final_result <- dplyr::mutate(extract_result,
115 +
                                lat = as.numeric(lat),
116 +
                                long = as.numeric(long))
117 +
118 +
  final_result <- dplyr::select(final_result,
119 +
                                type,
120 +
                                involved_person,
121 +
                                datetime,
122 +
                                lat,
123 +
                                long,
124 +
                                street_id,
125 +
                                street_name,
126 +
                                dplyr::everything())
127 +
128 +
  return(final_result)
129 +
130 +
} # end function
131 +
132 +
#' @name ukp_stop_search
133 +
#' @examples
134 +
#'
135 +
#' # with 3 points
136 +
#' poly_df_3 = data.frame(lat = c(52.268, 52.794, 52.130),
137 +
#'                        long = c(0.543, 0.238, 0.478))
138 +
#'
139 +
#' ukp_data_poly_3 <- ukp_stop_search_poly(poly_df_3)
140 +
#' head(ukp_data_poly_3)
141 +
#'
142 +
#' # with 4 points
143 +
#' poly_df_4 = data.frame(lat = c(52.268, 52.794, 52.130, 52.000),
144 +
#'                        long = c(0.543,  0.238,  0.478,  0.400))
145 +
#' ukp_data_poly_4 <- ukp_stop_search_poly(poly_df = poly_df_4)
146 +
#'
147 +
#' head(ukp_data_poly_4)
148 +
#'
149 +
#' @export
150 +
ukp_stop_search_poly <- function(poly_df,
151 +
                                 date = NULL,
152 +
                                 ...){
153 +
154 +
  # poly must be a dataframe
155 +
  stopifnot(inherits(poly_df, "data.frame"))
156 +
157 +
  # "poly_df must contain columns named 'lat' and 'long'"
158 +
  stopifnot(c("lat", "long") %in% names(poly_df))
159 +
160 +
  poly_string <- ukp_poly_paste(poly_df,
161 +
                                "long",
162 +
                                "lat")
163 +
164 +
  # if date is used
165 +
  if (!is.null(date)) {
166 +
    api_string <- glue::glue("api/stops-street?poly={poly_string}&date={date}")
167 +
    # else if no date is specified
168 +
  } else if (is.null(date)) {
169 +
    api_string <- glue::glue("api/stops-street?poly={poly_string}")
170 +
  } # end ifelse
171 +
172 +
  result <- ukp_api(api_string)
173 +
174 +
  extract_result <- purrr::map_dfr(.x = result$content,
175 +
                                   .f = ukp_crime_unlist)
176 +
177 +
  # rename the data
178 +
  extract_result <- dplyr::rename(
179 +
    extract_result,
180 +
    lat = location.latitude,
181 +
    long = location.longitude,
182 +
    street_id = location.street.id,
183 +
    street_name = location.street.name,
184 +
    outcome_object_id = outcome_object.id,
185 +
    outcome_object_name = outcome_object.name,
186 +
  )
187 +
188 +
  final_result <- dplyr::mutate(extract_result,
189 +
                                lat = as.numeric(lat),
190 +
                                long = as.numeric(long))
191 +
192 +
  final_result <- dplyr::select(final_result,
193 +
                                datetime,
194 +
                                lat,
195 +
                                long,
196 +
                                street_id,
197 +
                                street_name,
198 +
                                dplyr::everything())
199 +
200 +
  return(final_result)
201 +
202 +
} # end function
203 +
204 +
#' ukp_crime_street_outcome
205 +
#' ukp_crime_location
206 +
#' ukp_crime_no_location
207 +
#' ukp_crime_categories
208 +
209 +
# Outcomes for a specific crime:
210 +
# https://data.police.uk/docs/method/outcomes-for-crime/
211 +
#' ukp_crime_outcome
212 +
1 213
# Stop and search related
2 -
  # Stop and searches by area
3 -
  # Stop and searches by location
4 -
  # Stop and searches with no location
5 -
  # Stop and searches by force
214 +
# Stop and searches by area
215 +
# Stop and searches by location
216 +
# Stop and searches with no location
217 +
# Stop and searches by force
Files Coverage
R 90.54%
Project Totals (5 files) 90.54%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading