Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dgkf/parttime
Work-in-progress R package for handling partial datetimes
https://github.com/dgkf/parttime
hacktoberfest
Last synced: 3 days ago
JSON representation
Work-in-progress R package for handling partial datetimes
- Host: GitHub
- URL: https://github.com/dgkf/parttime
- Owner: dgkf
- License: other
- Created: 2019-09-07T00:34:01.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2024-01-26T20:57:27.000Z (11 months ago)
- Last Synced: 2024-12-04T05:39:56.085Z (9 days ago)
- Topics: hacktoberfest
- Language: R
- Homepage: https://dgkf.github.io/parttime
- Size: 6.72 MB
- Stars: 17
- Watchers: 5
- Forks: 1
- Open Issues: 8
-
Metadata Files:
- Readme: README.Rmd
- Changelog: NEWS.md
- License: LICENSE
Awesome Lists containing this project
- jimsghstars - dgkf/parttime - Work-in-progress R package for handling partial datetimes (R)
README
---
output: github_document
---```{r, include = FALSE}
options(crayon.enabled = FALSE, width = 80)
library(parttime)knitr::opts_chunk$set(collapse = TRUE)
```# parttime
[![CRAN](https://img.shields.io/cran/v/parttime.svg)](https://cran.r-project.org/package=parttime)
![status](https://img.shields.io/static/v1?label=status&message=developing&color=orange)
[![R-CMD-check](https://github.com/dgkf/parttime/workflows/R-CMD-check/badge.svg)](https://github.com/dgkf/parttime/actions)
[![Coverage](https://codecov.io/gh/dgkf/parttime/branch/main/graph/badge.svg)](https://app.codecov.io/gh/dgkf/parttime?branch=main)A package for a partial datetime class and generics
# Installation
```{r, eval = FALSE}
devtools::install_github("dgkf/parttime")
```# Quick Start
The `parttime` package aims to make uncertainty in datetimes a central feature
by offering the `partial_time` datetime class.This includes:
- parsing of a wider range of datetime string formats
- internal representations that captures date component missingness
- overloading of operators for comparison
- mechanisms for resolving datetime uncertainty
- imputation## Overview
`partial_time`s can be parsed from strings. Any missing data is not immediately
imputed with a known date. Instead, its uncertainty is preserved as a central
part of the `partial_time` class.```{r, include = FALSE}
curyear <- substring(Sys.Date(), 1, 4)
dates <- paste0(curyear, c("", "-02"))
code <- deparse(bquote(pttms <- as.parttime(.(dates))))
``````{r, code = code}
```We can access the components of each datetime as though the `partial_time` is a
matrix of datetime fields, or using `lubridate`-style accessors and assignment
functions.```{r, access_and_assign}
pttms[, "year"]pttms[[1, "year"]]
year(pttms) # the first row are names of elements in a named numeric vector
year(pttms[1])
month(pttms[2]) <- 3
pttmsmonth(pttms[1]) <- 3
pttmsmonth(pttms) <- NA
pttms
```Because `partial_time` objects may have uncertainty, comparison between times
conveys this uncertainty. As a brief example, if we compare our dates from
above we see that it is unclear whether one is greater-than the other.```{r, code = code}
``````{r, comparison}
pttms[1] > pttms[2]pttms[2] > pttms[1]
```This is because `"2022"` could be any date within the calendar year (and even
outside the calendar year if the timezone is unknown!, see
[below](#partial-datetime-comparisons)). In this sense, there are two other
modes of comparison - to determine whether a `partial_time` _possibly_ or
_definitely_ satisfies a criteria.```{r, comparison-resolver}
definitely(pttms[1] > pttms[2])possibly(pttms[2] > pttms[1])
```As well, a few helper functions are provided to perform imputation. All
imputation functions are wrappers around `impute_time` with varying defaults for
default timestamp and resolution to which imputation is performed.```{r, imputation}
impute_date_max(pttms[2]) # resolve date fields with maximum valueimpute_time(pttms[1], "1999-06-05T04:03:02") # arbitrary imputation
```## The `partial_time` class
`partial_time`s are like any other time, but may include `NA`s for some of their
fields. For example, `"1999"` only tells us information about a year, the month,
day, hour, etc. are still unknown. `partial_time`s should be used for situations
when a specific point in time is intended, but exactly when it occurred is
unknown.## The `timespan` class
Similarly, a `timespan` class is offered, which is meant to represent a range of
times, denoted by a starting and ending `partial_time`. Timespans might
represent a range from the start to the end of a day, like a `partial_time`, but
can also represent ranges where the start and end are partial times with
different resolution.# Examples
## Parsing Incomplete Timestamps
Parse ISO8601 timestampes using the `parsedate` package's parser, but retains
information about missingness in the timestamp format.```{r}
iso8601_dates <- c(
NA,
"2001",
"2002-01-01",
"2004-245", # yearday
"2005-W13", # yearweek
"2006-W02-5", # yearweek + weekday
"2007-10-01T08",
"2008-09-20T08:35",
"2009-08-12T08:35.048", # fractional minute
"2010-07-22T08:35:32",
"2011-06-13T08:35:32.123", # fractional second
"2012-05-23T08:35:32.123Z", # Zulu time
"2013-04-14T08:35:32.123+05", # time offset from GMT
"2014-03-24T08:35:32.123+05:30", # time offset with min from GMT
"20150101T083532.123+0530" # condensed form
)as.parttime(iso8601_dates)
```## Imputing Timestamps
```{r}
impute_time("2019", "2000-01-02T03:04:05.006+07:30")
```## Partial Datetime Comparisons
Partial timestamps include uncertainty, which means that there is often
uncertainty when comparing between timestamps. To help resolve this uncertainty
there are two helper functions, `possibly` and `definitely` resolving this
uncertainty for when the windows of uncertainty overlap, or equal (to a given
resolution).```{r}
options(parttime.assume_tz_offset = 0) # assume GMT
parttime(2019) < parttime(2020)options(parttime.assume_tz_offset = NA) # don't assume a timezone
parttime(2019) < parttime(2020)possibly(parttime(2019) < parttime(2020))
definitely(parttime(2019) < parttime(2020))
```Given uncertainty in timestamps, we can't be sure these are equal. In this
situation, `==` will return `NA`.```{r}
parttime(2019) == parttime(2019)options(parttime.assume_tz_offset = 0)
definitely(parttime(2019) == parttime(2019), by = "year")options(parttime.assume_tz_offset = NA)
definitely(parttime(2019) == parttime(2019), by = "year")
```## Timespans
Cast a partial time's missingness to a range of possible values
```{r}
as.timespan(parttime(2019))
```## Tidyverse Compatible `vctrs`
`tibble`-style formatting makes it easy to see which components of each
`partial_time` are missing.```{r}
library(dplyr)tibble(dates = iso8601_dates) %>%
mutate(
parttimes = as.parttime(dates),
imputed_times = impute_time_min(parttimes)
)
```# Roadmap
## Summary
The `partial_time` class is pretty complete. The `timespan` and
`partial_difftime` classes are still under construction!## In-development :construction:
|status|class|function/op|description|status|
|---|---|---|---|
|:ballot_box_with_check:|`partial_time`|`parttime`|create `partial_time`|
|:ballot_box_with_check:|`partial_time`|`as.parttime`|cast to `partial_time`|
|:ballot_box_with_check:|`partial_time`|`>`,`<`,`<=`,`>=`|comparison operators|
|:ballot_box_with_check:|`partial_time`|`possibly`,`definitely`|uncertainty resolvers|
|:ballot_box_with_check:|`partial_time`|`==`,`!=`|equivalence operators|
|:ballot_box_with_check:|`partial_time`|`min`,`max`,`pmin`,`pmax`|partial time extremes|
|:ballot_box_with_check:|`partial_time`|`impute_time`|imputing partial time|
|:ballot_box_with_check:|`partial_time`|`to_gmt`|convert to gmt timezone|
|:ballot_box_with_check:|`partial_time`|`print`|printing|
|:ballot_box_with_check:|`partial_time`|`format`|format as character|
|:ballot_box_with_check:|`partial_time`|``|misc `vctrs` functions|
|:ballot_box_with_check:|`partial_time`|``|misc `pillar` functions|
|:black_square_button:|`partial_difftime`|`difftime`|create `partial_difftime`|︎
|:black_square_button:|`partial_difftime`|`as.difftime`|cast to `partial_difftime`|︎
|:black_square_button:|`partial_difftime`|`>`,`<`,`<=`,`>=`|comparison operators|︎
|:black_square_button:|`partial_difftime`|`possibly`,`definitely`|uncertainty resolvers|︎
|:black_square_button:|`partial_difftime`|`==`,`!=`|equivalence operators|︎
|:black_square_button:|`partial_difftime`|`min`,`max`,`pmin`,`pmax`|partial difftime extremes|︎
|:black_square_button:|`partial_difftime`|`print`|printing|
|:black_square_button:|`partial_difftime`|`format`|format as character|
|:black_square_button:|`partial_difftime`|``|misc `vctrs` functions|
|:black_square_button:|`partial_difftime`|``|misc `pillar` functions|
|:black_square_button:||``` `-`(partial_time, partial_difftime) ```|subraction|︎
|:black_square_button:||``` `-`(partial_time, partial_time) ```|subraction|︎
|:black_square_button:||``` `-`(partial_difftime, partial_difftime) ```|subraction|︎
|:black_square_button:||``` `-`(partial_difftime, partial_difftime) ```|addition|︎