Skip to content

Commit

Permalink
Closes #1765 -- new isoweek function produces ISO 8601-consistent wee…
Browse files Browse the repository at this point in the history
…k numbering as an integer

fix man
  • Loading branch information
MichaelChirico committed Aug 29, 2016
1 parent 437c440 commit 688660f
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 3 deletions.
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ S3method(na.omit, data.table)

# IDateTime support:
export(as.IDate,as.ITime,IDateTime)
export(second,minute,hour,yday,wday,mday,week,month,quarter,year)
export(second,minute,hour,yday,wday,mday,week,isoweek,month,quarter,year)

export(as.chron.IDate, as.chron.ITime)
export(as.Date.IDate) # workaround for zoo bug, see #1500
Expand Down
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@

43. `first()` is now exported to return the first element of vectors, data.frames and data.tables.

44. Added `second` and `minute` extraction functions which, like extant `hour`/`yday`/`week`/etc, always return an integer, [#874](https://github.com/Rdatatable/data.table/issues/874). Thanks to @bthieurmel for the FR and @MichaelChirico for the PR.
44. Added `second` and `minute` extraction functions which, like extant `hour`/`yday`/`week`/etc, always return an integer, [#874](https://github.com/Rdatatable/data.table/issues/874). Also added ISO 8601-consistent weeks in `isoweek`, [#1765](https://github.com/Rdatatable/data.table/issues/1765). Thanks to @bthieurmel and @STATWORX for the FRs and @MichaelChirico for the PRs.

44. `shift()` understands and operates on list-of-list inputs as well, [#1595](https://github.com/Rdatatable/data.table/issues/1595). Thanks to @enfascination and to @chris for [asking on SO](http://stackoverflow.com/q/38900293/559784).

Expand Down
19 changes: 19 additions & 0 deletions R/IDateTime.R
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,25 @@ yday <- function(x) as.POSIXlt(x)$yday + 1L
wday <- function(x) as.POSIXlt(x)$wday + 1L
mday <- function(x) as.POSIXlt(x)$mday
week <- function(x) yday(x) %/% 7L + 1L
isoweek <- function(x) {
#ISO 8601-conformant week, as described at
# https://en.wikipedia.org/wiki/ISO_week_date

#Approach:
# * Find nearest Thursday to each element of x
# * Find the number of weeks having passed between
# January 1st of the year of the nearest Thursdays and x

xlt <- as.POSIXlt(x)

#We want Thursday to be 3 (4 by default in POSIXlt), so
# subtract 1 and re-divide; also, POSIXlt increment by seconds
nearest_thurs <- xlt + (3 - ((xlt$wday - 1) %% 7)) * 86400

year_start <- as.POSIXct(paste0(as.POSIXlt(nearest_thurs)$year + 1900L, "-01-01"))

as.integer(1 + unclass(difftime(nearest_thurs, year_start, units = "days")) %/% 7)
}
month <- function(x) as.POSIXlt(x)$mon + 1L
quarter <- function(x) as.POSIXlt(x)$mon %/% 3L + 1L
year <- function(x) as.POSIXlt(x)$year + 1900L
Expand Down
14 changes: 14 additions & 0 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -9204,6 +9204,20 @@ test(1701.6, A[B, .(x.x, get("x.x"), x.y), on="x", by=.EACHI], data.table(x=c(2,
dt = data.table(a=1L)
test(1701.7, dt[dt, .(xa=x.a, ia=i.a), .EACHI, on="a"], data.table(a=1L, xa=1L, ia=1L))

# ISO 8601-consistent week numbering, #1765
# test cases via https://en.wikipedia.org/wiki/ISO_week_date
test_cases <- c("2005-01-01", "2005-01-02", "2005-12-31",
"2007-01-01", "2007-12-30", "2007-12-31",
"2008-01-01", "2008-12-28", "2008-12-29",
"2008-12-30", "2008-12-31", "2009-01-01",
"2009-12-31", "2010-01-01",
"2010-01-02", "2010-01-03")

test_values <- c(53L, 53L, 52L, 1L, 52L, 1L, 1L,
52L, 1L, 1L, 1L, 1L, 53L, 53L, 53L, 53L)

test(1702, isoweek(test_cases), test_values)

##########################

# TODO: Tests involving GForce functions needs to be run with optimisation level 1 and 2, so that both functions are tested all the time.
Expand Down
5 changes: 4 additions & 1 deletion man/IDateTime.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
\alias{wday}
\alias{mday}
\alias{week}
\alias{isoweek}
\alias{month}
\alias{quarter}
\alias{year}
Expand Down Expand Up @@ -73,6 +74,7 @@ yday(x)
wday(x)
mday(x)
week(x)
isoweek(x)
month(x)
quarter(x)
year(x)
Expand Down Expand Up @@ -135,7 +137,7 @@ intervals. \code{as.POSIXlt} is also useful. For example,
\code{as.POSIXlt(x)$mon} is the integer month. The R base convenience
functions \code{weekdays}, \code{months}, and \code{quarters} can also
be used, but these return character values, so they must be converted to
factors for use with data.table.
factors for use with data.table. \code{isoweek} is ISO 8601-consistent.

The \code{round} method for IDate's is useful for grouping and plotting. It can
round to weeks, months, quarters, and years.
Expand Down Expand Up @@ -168,6 +170,7 @@ round to weeks, months, quarters, and years.
H. Wickham, http://gist.github.com/10238.
ISO 8601, http://www.iso.org/iso/home/standards/iso8601.htm
}
\author{ Tom Short, t.short@ieee.org }
Expand Down

0 comments on commit 688660f

Please sign in to comment.