The goal of aoristic is to make sense of temporally vague data. It can be difficult to ascertain when some events, such as property crime, occur because the victim is not present when the crime happens. Police databases therefore often record a start (or from) date and time and an end (or to) date and time. The period between them is the event’s time span.
The time span can be minutes, hours, or days: hence the term aoristic. It has its origins in the Greek word aoristos, meaning undefined. For events with a latitude/longitude or X/Y coordinate pair and start and end datetimes, this package generates weighted probabilities for every hour of the week. Various descriptive and graphical outputs are available.
An R-devel change in 2022 redefined some POSIXt calculations and caused errors in aoristic duration calculations. Version 1.1.1 added a compatibility workaround, which is no longer needed on supported R versions.
aoristic.plot() function.Version 0.6 was originally released on CRAN in 2015 by Dr. George Kikuchi, then of Fresno State University and now at the Philadelphia Police Department. With his permission, maintenance was taken over in 2020 by Dr. Jerry Ratcliffe. The package is now maintained at the University of Pennsylvania.
Version 1.0.0 replaced rounding to the nearest hour with a minute-by-minute method. For example, an event between 10:55 and 11:55 assigns 5/60 of its weight to 10:00-10:59 and 55/60 to 11:00-11:59. Earlier versions assigned 0.5 to each hour.
The KML mapping function from version 0.6 was replaced with a simpler
plot function for a user-selected hour; see ?aoristic.map.
The graph function plots the overall weekly distribution and each day
separately; see ?aoristic.graph.
Install the released version from CRAN:
install.packages("aoristic")Install the development version from the canonical GitHub repository:
# install.packages("devtools")
devtools::install_github("jerry-ratcliffe/aoristic")The main challenge is usually getting datetime variables into the
correct format. aoristic.df() accepts a data frame and four
column names:
Xcoord: numeric X coordinate or latitude;Ycoord: numeric Y coordinate or longitude;DateTimeFrom: From/Start datetime as POSIXct;DateTimeTo: To/End datetime as POSIXct.The lubridate package can help prepare datetime
fields. The included NYburg data contain separate date and
time fields:
library(aoristic)
data(NYburg)
head(NYburg)
#> CMPLNT_FR_DT CMPLNT_FR_TM CMPLNT_TO_DT CMPLNT_TO_TM X_COORD_CD Y_COORD_CD
#> 30 2019-01-04 0.6180556 2019-01-04 0.6444444 982546 206109
#> 78 2019-01-01 0.7847222 2019-01-01 0.7909722 985962 202878
#> 127 2019-01-01 0.3125000 2019-01-01 0.3361111 999874 238251
#> 203 2019-01-02 0.5416667 2019-01-02 0.7708333 1001526 243602
#> 216 2019-01-04 0.7500000 2019-01-04 0.8333333 983355 211219
#> 233 2019-01-01 0.2083333 2019-01-01 0.3361111 999874 238251The time variables are fractions of a day. First convert them to readable times:
NYburg$CMPLNT_FR_TM <- format(
as.POSIXct(NYburg$CMPLNT_FR_TM * 86400, origin = "1970-01-01", tz = "UTC"),
"%H:%M"
)
NYburg$CMPLNT_TO_TM <- format(
as.POSIXct(NYburg$CMPLNT_TO_TM * 86400, origin = "1970-01-01", tz = "UTC"),
"%H:%M"
)Combine each date and time, then parse it with an explicit timezone matching the source data:
NYburg$STARTDateTime <- paste(NYburg$CMPLNT_FR_DT, NYburg$CMPLNT_FR_TM)
NYburg$ENDDateTime <- paste(NYburg$CMPLNT_TO_DT, NYburg$CMPLNT_TO_TM)
NYburg$STARTDateTime <- lubridate::ymd_hm(
NYburg$STARTDateTime, tz = "America/New_York"
)
NYburg$ENDDateTime <- lubridate::ymd_hm(
NYburg$ENDDateTime, tz = "America/New_York"
)
#> Warning: 49 failed to parse.Some End/To values may be missing. This often indicates that the event time is known from the Start/From value alone. Check the prepared data before analysis:
aor.chk.df <- aoristic.datacheck(
NYburg,
"X_COORD_CD", "Y_COORD_CD",
"STARTDateTime", "ENDDateTime"
)
#>
#> ---- Aoristic data check -------------------------------------------
#> 49 rows were missing END/TO datetime values.
#> 0 rows had END/TO datetimes before START/FROM datetimes.
#> In the aoristic.datacheck data frame these rows are indicated
#> with missing end datetimes = 1 and start/end logical errors = 2.
#> See the aoristic_datacheck column and ?aoristic.datacheck.
#> Coordinates check:
#> No missing or zero coordinates.aoristic.df() assigns a missing End/To or a reversed
interval entirely to the Start/From hour. An interval lasting at least
one week receives a uniform probability of 1/168 in every
hour.