Skip to content

Commit fac31b1

Browse files
authored
Merge branch 'master' into coerce-j-warn
2 parents 4b797b4 + 16c6fdc commit fac31b1

28 files changed

+1066
-958
lines changed

NAMESPACE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ if (getRversion() >= "3.6.0") {
153153

154154
# IDateTime support:
155155
export(as.IDate,as.ITime,IDateTime)
156-
export(second,minute,hour,yday,wday,mday,week,isoweek,month,quarter,year,yearmon,yearqtr)
156+
export(second,minute,hour,yday,wday,mday,week,isoweek,isoyear,month,quarter,year,yearmon,yearqtr)
157157

158158
S3method("[", ITime)
159159
S3method("+", IDate)

NEWS.md

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,16 @@
1010

1111
### NEW FEATURES
1212

13-
1. New `sort_by()` method for data.tables, [#6662](https://github.com/Rdatatable/data.table/issues/6662). It uses `forder()` to improve upon the data.frame method and also match `DT[order(...)]` behavior with respect to locale. Thanks @rikivillalba for the suggestion and PR.
13+
1. New `sort_by()` method for data.tables, [#6662](https://github.com/Rdatatable/data.table/issues/6662). It uses `forder()` to improve upon the data.frame method and also matches `DT[order(...)]` behavior with respect to locale. Thanks @rikivillalba for the suggestion and PR.
14+
15+
```r
16+
DT = data.table(a=c(1L, 2L, 1L), b=c(3L, 1L, 2L))
17+
sort_by(DT, ~a + b)
18+
# a b
19+
# 1: 1 2
20+
# 2: 1 3
21+
# 3: 2 1
22+
```
1423

1524
2. `melt()` now supports using `patterns()` with `id.vars`, [#6867](https://github.com/Rdatatable/data.table/issues/6867). Thanks to Toby Dylan Hocking for the suggestion and PR.
1625

@@ -56,6 +65,10 @@
5665

5766
13. New `mergelist()` and `setmergelist()` similarly work _a la_ `Reduce()` to recursively merge a `list` of data.tables, [#599](https://github.com/Rdatatable/data.table/issues/599). Different join modes (_left_, _inner_, _full_, _right_, _semi_, _anti_, and _cross_) are supported through the `how` argument; duplicate handling goes through the `mult` argument. `setmergelist()` carefully avoids copies where one is not needed, e.g. in a 1:1 left join. Thanks Patrick Nicholson for the FR (in 2013!), @jangorecki for the PR, and @MichaelChirico for extensive reviews and fine-tuning.
5867

68+
14. `fcoalesce()` and `setcoalesce()` gain `nan` argument to control whether `NaN` values should be treated as missing (`nan=NA`, the default) or non-missing (`nan=NaN`), [#4567](https://github.com/Rdatatable/data.table/issues/4567). This provides full compatibility with `nafill()` behavior. Thanks to @ethanbsmith for the feature request and @Mukulyadav2004 for the implementation.
69+
70+
15. New function `isoyear()` has been implemented as a complement to `isoweek()`, returning the ISO 8601 year corresponding to a given date, [#7154](https://github.com/Rdatatable/data.table/issues/7154). Thanks to @ben-schwen and @MichaelChirico for the suggestion and @venom1204 for the implementation.
71+
5972
### BUG FIXES
6073

6174
1. `fread()` no longer warns on certain systems on R 4.5.0+ where the file owner can't be resolved, [#6918](https://github.com/Rdatatable/data.table/issues/6918). Thanks @ProfFancyPants for the report and PR.
@@ -74,7 +87,7 @@
7487
7588
8. A data.table with a column of class `vctrs_list_of` (from package {vctrs}) prints as expected, [#5948](https://github.com/Rdatatable/data.table/issues/5948). Before, they could be printed messily, e.g. printing every entry in a nested data.frame. Thanks @jesse-smith for the report, @DavisVaughan and @r2evans for contributing, and @MichaelChirico for the PR.
7689
77-
9. Fixed incorrect sorting of merges where the first column of a key is a factor with non-`sort()`-ed levels (e.g. `factor(1:2, 2:1)` and it is joined to a character column, [#5361](https://github.com/Rdatatable/data.table/issues/5361). Thanks to @gbrunick for the report and Benjamin Schwendinger for the fix.
90+
9. Fixed incorrect sorting of merges where the first column of a key is a factor with non-`sort()`-ed levels (e.g. `factor(1:2, 2:1)` and it is joined to a character column, [#5361](https://github.com/Rdatatable/data.table/issues/5361). Thanks to @gbrunick for the report, Benjamin Schwendinger for the fix, and @MichaelChirico for a follow-up fix caught by revdep testing.
7891
7992
10. Spurious warnings from internal code in `cube()`, `rollup()`, and `groupingsets()` are no longer surfaced to the caller, [#6964](https://github.com/Rdatatable/data.table/issues/6964). Thanks @ferenci-tamas for the report and @venom1204 for the fix.
8093
@@ -86,6 +99,8 @@
8699
87100
14. Filling columns of class Date with POSIXct (and vice versa) using `shift()` now yields a clear, informative error message specifying the class mismatch, [#5218](https://github.com/Rdatatable/data.table/issues/5218). Thanks @ashbaldry for the report and @ben-schwen for the fix.
88101
102+
15. `split.data.table()` output list elements retain the S3 class of the generating data.table, e.g. in `l=split(x, ...)` if `x` has class `my_class`, so will `l[[1]]` and so on, [#7105](https://github.com/Rdatatable/data.table/issues/7105). Thanks @m-muecke for the bug report and @MichaelChirico for the fix.
103+
89104
### NOTES
90105
91106
1. The following in-progress deprecations have proceeded:
@@ -109,21 +124,21 @@
109124
110125
6. Using a double vector in `set()`'s `i=` and/or `j=` no longer throws a warning about preferring integer, [#6594](https://github.com/Rdatatable/data.table/issues/6594). While it may improve efficiency to use integer, there's no guarantee it's an improvement and the difference is likely to be minimal. The coercion will still be reported under `datatable.verbose=TRUE`. For package/production use cases, static analyzers such as `lintr::implicit_integer_linter()` can also report when numeric literals should be rewritten as integer literals.
111126

112-
# data.table [v1.17.8](https://github.com/Rdatatable/data.table/milestone/41) (6 July 2025)
127+
## data.table [v1.17.8](https://github.com/Rdatatable/data.table/milestone/41) (6 July 2025)
113128

114129
1. Internal functions used to signal errors are now marked as non-returning, silencing a compiler warning about potentially unchecked allocation failure. Thanks to Prof. Brian D. Ripley for the report and @aitap for the fix, [#7070](https://github.com/Rdatatable/data.table/pull/7070).
115130

116-
# data.table [v1.17.6](https://github.com/Rdatatable/data.table/milestone/40) (15 June 2025)
131+
## data.table [v1.17.6](https://github.com/Rdatatable/data.table/milestone/40) (15 June 2025)
117132

118133
1. On a heavily loaded machine, a `forder` thread could try to perform a zero-length copy from a null pointer, which was de-facto harmless but is against the C standard and was caught by additional CRAN checks, [#7051](https://github.com/Rdatatable/data.table/issues/7051). Thanks to @helske for the report and @aitap for the PR.
119134

120-
# data.table [v1.17.4](https://github.com/Rdatatable/data.table/milestone/39) (25 May 2025)
135+
## data.table [v1.17.4](https://github.com/Rdatatable/data.table/milestone/39) (25 May 2025)
121136

122137
1. The C code now avoids passing invalid data pointers from 0-length vectors to `memcpy()`, which previously caused undefined behaviour. Thanks to Prof. Brian D. Ripley for the report and Michael Chirico for the fix, [#6911](https://github.com/Rdatatable/data.table/pull/6911).
123138

124-
# data.table [v1.17.2](https://github.com/Rdatatable/data.table/milestone/38) (7 May 2025)
139+
## data.table [v1.17.2](https://github.com/Rdatatable/data.table/milestone/38) (7 May 2025)
125140

126-
## BUG FIXES
141+
### BUG FIXES
127142

128143
1. `fwrite(compress="gzip")` once again produces a gzip header when the column names are missing or disabled, [@6852](https://github.com/Rdatatable/data.table/issues/6852). Thanks @maxscheiber for the report and @aitap for the fix.
129144

@@ -139,7 +154,7 @@
139154

140155
7. `as.data.table()` now properly handles keys: specifying keys sets them, omitting keys preserves existing ones, and setting `key=NULL` clears them, [#6859](https://github.com/Rdatatable/data.table/issues/6859). Thanks @brookslogan for the report and @Mukulyadav2004 for the fix.
141156

142-
## NOTES
157+
### NOTES
143158

144159
1. Continued work to remove non-API C functions, [#6180](https://github.com/Rdatatable/data.table/issues/6180). Thanks Ivan Krylov for the PRs and for writing a clear and concise guide about the R API: https://aitap.codeberg.page/R-api/.
145160

R/IDateTime.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ isoweek = function(x) as.integer(format(as.IDate(x), "%V"))
355355
# nearest_thurs = as.IDate(7L * (as.integer(x + 3L) %/% 7L))
356356
# year_start = as.IDate(format(nearest_thurs, '%Y-01-01'))
357357
# 1L + (nearest_thurs - year_start) %/% 7L
358-
358+
isoyear = function(x) as.integer(format(as.IDate(x), "%G"))
359359

360360
month = function(x) convertDate(as.IDate(x), "month")
361361
quarter = function(x) convertDate(as.IDate(x), "quarter")

R/between.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ between = function(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE,
3030
}
3131
if (is.i64(x)) {
3232
if (!requireNamespace("bit64", quietly=TRUE)) stopf("trying to use integer64 class when 'bit64' package is not installed") # nocov
33-
if (!is.i64(lower) && is.numeric(lower)) lower = bit64::as.integer64(lower)
34-
if (!is.i64(upper) && is.numeric(upper)) upper = bit64::as.integer64(upper)
33+
if (!is.i64(lower) && (is.integer(lower) || fitsInInt64(lower))) lower = bit64::as.integer64(lower)
34+
if (!is.i64(upper) && (is.integer(upper) || fitsInInt64(upper))) upper = bit64::as.integer64(upper)
3535
}
3636
is.supported = function(x) is.numeric(x) || is.character(x) || is.px(x)
3737
if (is.supported(x) && is.supported(lower) && is.supported(upper)) {

R/data.table.R

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,8 +2047,9 @@ replace_dot_alias = function(e) {
20472047
if (!.Call(CisOrderedSubset, irows, nrow(x)))
20482048
return(NULL)
20492049

2050-
# see #1010. don't set key when i has no key, but irows is ordered and !roll
2051-
if (roll && length(irows) != 1L)
2050+
# see #1010. don't set key when i has no key, but irows is ordered and isFALSE(roll)
2051+
# NB: roll could still be a string like 'nearest', #7146
2052+
if (!is.character(roll) && roll && length(irows) != 1L)
20522053
return(NULL)
20532054

20542055
new_key <- head(x_key, key_length)
@@ -2491,7 +2492,7 @@ Ops.data.table = function(e1, e2 = NULL)
24912492
}
24922493

24932494
split.data.table = function(x, f, drop = FALSE, by, sorted = FALSE, keep.by = TRUE, flatten = TRUE, ..., verbose = getOption("datatable.verbose")) {
2494-
if (!is.data.table(x)) stopf("x argument must be a data.table")
2495+
if (!is.data.table(x)) internal_error("x argument to split.data.table must be a data.table") # nocov
24952496
stopifnot(is.logical(drop), is.logical(sorted), is.logical(keep.by), is.logical(flatten))
24962497
# split data.frame way, using `f` and not `by` argument
24972498
if (!missing(f)) {
@@ -2566,8 +2567,11 @@ split.data.table = function(x, f, drop = FALSE, by, sorted = FALSE, keep.by = TR
25662567
setattr(ll, "names", nm)
25672568
# handle nested split
25682569
if (flatten || length(by) == 1L) {
2569-
for (x in ll) .Call(C_unlock, x)
2570-
lapply(ll, setDT)
2570+
for (xi in ll) .Call(C_unlock, xi)
2571+
out = lapply(ll, setDT)
2572+
# TODO(#2000): just let setDT handle this
2573+
if (!identical(old_class <- class(x), c("data.table", "data.frame"))) for (xi in out) setattr(xi, "class", old_class)
2574+
out
25712575
# alloc.col could handle DT in list as done in: c9c4ff80bdd4c600b0c4eff23b207d53677176bd
25722576
} else if (length(by) > 1L) {
25732577
lapply(ll, split.data.table, drop=drop, by=by[-1L], sorted=sorted, keep.by=keep.by, flatten=flatten)

R/wrappers.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
# Very small (e.g. one line) R functions that just call C.
33
# One file wrappers.R to avoid creating lots of small .R files.
44

5-
fcoalesce = function(...) .Call(Ccoalesce, list(...), FALSE)
6-
setcoalesce = function(...) .Call(Ccoalesce, list(...), TRUE)
5+
fcoalesce = function(..., nan=NA) .Call(Ccoalesce, list(...), FALSE, nan_is_na(nan))
6+
setcoalesce = function(..., nan=NA) .Call(Ccoalesce, list(...), TRUE, nan_is_na(nan))
77

88
fifelse = function(test, yes, no, na=NA) .Call(CfifelseR, test, yes, no, na)
99
fcase = function(..., default=NA) {

inst/tests/nafill.Rraw

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ test(3.02, setnafill(list(copy(x)), "locf", fill=0L), list(x))
114114
test(3.03, setnafill(x, "locf"), error="in-place update is supported only for list")
115115
test(3.04, nafill(letters[1:5], fill=0), error="must be numeric type, or list/data.table")
116116
test(3.05, setnafill(list(letters[1:5]), fill=0), error="must be numeric type, or list/data.table")
117-
test(3.06, nafill(x, fill=1:2), error="fill must be a vector of length 1")
118-
test(3.07, nafill(x, fill="asd"), x, warning=c("Coercing.*character.*integer","NAs introduced by coercion"))
117+
test(3.06, nafill(x, fill=1:2), error="fill must be a vector of length 1.*fcoalesce")
118+
test(3.07, nafill(x, "locf", fill=1:2), error="fill must be a vector of length 1.*x\\.$")
119+
test(3.08, nafill(x, fill="asd"), x, warning=c("Coercing.*character.*integer","NAs introduced by coercion"))
119120

120121
# colnamesInt helper
121122
dt = data.table(a=1, b=2, d=3)

inst/tests/tests.Rraw

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ if (exists("test.data.table", .GlobalEnv, inherits=FALSE)) {
7474
setfrev = data.table:::setfrev
7575
shallow = data.table:::shallow # until exported
7676
.shallow = data.table:::.shallow
77-
split.data.table = data.table:::split.data.table
7877
stopf = data.table:::stopf
7978
test = data.table:::test
8079
uniqlengths = data.table:::uniqlengths
@@ -6852,11 +6851,12 @@ test(1463.79, shift(x,-1L, type="cyclic"), as.raw(c(2:5, 1)))
68526851
test(1463.80, shift(x,-(1:2),type="cyclic"), list(as.raw(c(2:5, 1)), as.raw(c(3:5,1:2))))
68536852

68546853
# shift incompatible types (e.g. Date and POSIXct)
6855-
d = .Date(0:4)
6854+
# TODO(R>=3.5): use .Date() instead of setting class by hand
6855+
d = structure(0:4, class="Date")
68566856
p = .POSIXct(1:5)
68576857
test(1463.81, shift(d, fill=p[1L]), error="Filling Date with POSIXct .* unsupported.*")
68586858
test(1463.82, shift(p, fill=d[1L]), error="Filling POSIXct with Date .* unsupported.*")
6859-
test(1463.83, shift(d, fill=as.IDate(2000L)), .Date(c(2000L, 0:3)))
6859+
test(1463.83, shift(d, fill=as.IDate(2000L)), structure(c(2000L, 0:3), class="Date"))
68606860

68616861
# FR #686
68626862
DT = data.table(a=rep(c("A", "B", "C", "A", "B"), c(2,2,3,1,2)), foo=1:10)
@@ -7131,6 +7131,11 @@ dt3 <- merge(dt1, dt2, by="x")
71317131
test(1483.81, key(dt3), "x")
71327132
test(1483.82, nrow(dt3[x %in% "c", ]), 2L)
71337133

7134+
# avoid regression of roll='nearest' join of int->double, #7146
7135+
DT1 <- data.table(a=1L, key='a')
7136+
DT2 <- data.table(a=2.0, key='a')
7137+
test(1483.83, DT1[DT2, roll='nearest'], data.table(a=2L, key='a'))
7138+
71347139
# NULL items should be removed when making data.table from list, #842
71357140
# Original fix for #842 added a branch in as.data.table.list() using point()
71367141
# Then PR#3471 moved logic from data.table() into as.data.table.list() and now removes NULL items up front, so longer need for the branch
@@ -9763,6 +9768,14 @@ test(1639.141, all(sapply(dtL, truelength) > 1000))
97639768
dt <- data.table(x = factor("a"), y = 1)
97649769
test(1639.142, x = split(dt, by = "x"), y = list(a = dt))
97659770
test(1639.143, x = split(dt, by = "y"), y = list(`1` = dt))
9771+
9772+
# retain a custom class after splitting, #7105
9773+
DT = data.table(x=letters[1:10], y=1:10, z=rnorm(10))
9774+
setattr(DT, "class", c("my_class", class(DT)))
9775+
test(1639.144, "my_class" %in% unlist(lapply(split(DT, by="x"), class)))
9776+
test(1639.145, "my_class" %in% unlist(lapply(split(DT, ~x), class)))
9777+
test(1639.146, "my_class" %in% unlist(lapply(split(DT, by=c("x", "y")), class)))
9778+
test(1639.147, "my_class" %in% unlist(lapply(split(DT, ~x+y), class)))
97669779
rm_all()
97679780

97689781
# allow x's cols (specifically x's join cols) to be referred to using 'x.' syntax
@@ -14276,7 +14289,7 @@ test(1984.25, rbindlist(list(DT[1L], DT[2L]), idcol = TRUE), data.table(.id=1:2,
1427614289
test(1984.26, setalloccol(`*tmp*`), error='setalloccol attempting to modify `*tmp*`')
1427714290
DF = as.data.frame(DT)
1427814291
test(1984.27, identical(shallow(DF), DF)) # shallow (which is not exported) works on DF from v1.14.2. identical() to force checking the selfref attribute for #5286.
14279-
test(1984.28, split.data.table(DF), error='argument must be a data.table')
14292+
# 1984.28 was a coverage test converted to 'nocov' of an internal_error instead
1428014293
test(1984.29, split(DT, by='a', f='a'), error="passing 'f' argument together with 'by' is not allowed")
1428114294
test(1984.30, split(DT), error="Either 'by' or 'f' argument must be supplied")
1428214295
setnames(DT, '.ll.tech.split')
@@ -15060,7 +15073,7 @@ if (test_bit64) {
1506015073
as.i64 = bit64::as.integer64
1506115074
test(2039.01, between(1:10, as.i64(3), as.i64(6)), error="x is not integer64 but.*Please align classes")
1506215075
test(2039.02, between(1:10, 3, as.i64(6)), error="x is not integer64 but.*Please align classes")
15063-
test(2039.03, between(as.i64(1:3), "2", as.i64(4)), error="x is integer64 but lower and/or upper are not")
15076+
test(2039.03, between(as.i64(1:3), "2", as.i64(4)), error="x is integer64 but lower is not.*Please align classes")
1506415077
old = options("datatable.verbose"=TRUE)
1506515078
x = as.i64(1:10)
1506615079
ans36 = c(FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE)
@@ -15087,6 +15100,10 @@ if (test_bit64) {
1508715100
test(2039.19, between(x+maxint, 3+maxint, NA, incbounds=FALSE), c(head(ans36open, -5L), rep(TRUE, 5)), output="between parallel processing of integer64 took")
1508815101
test(2039.20, between(x+maxint, rep(NA, 10L), rep(6+maxint, 10L)), c(TRUE, TRUE, tail(ans36, -2L)), output="between parallel processing of integer64 took")
1508915102
test(2039.21, between(x+maxint, rep(3+maxint, 10L), rep(NA, 10L), incbounds=FALSE), c(head(ans36open, -5L), rep(TRUE, 5)), output="between parallel processing of integer64 took")
15103+
# must not blindly read integer64 values as doubles when the latter fit into int32, #7164
15104+
test(2039.22, between(42L, structure(41., class="integer64"), structure(43., class="integer64")), error="x is not integer64 but.*Please align classes")
15105+
# must not blindly convert numeric bounds to integer64, #7164
15106+
test(2039.23, between(as.i64(42), 41, -2^98), error="x is integer64 but upper is not.*Please align classes")
1509015107
options(old)
1509115108
}
1509215109

@@ -15578,6 +15595,11 @@ test(2060.154, fcoalesce(list(x)), x)
1557815595
test(2060.155, setcoalesce(list(x)), x)
1557915596
test(2060.156, setcoalesce(list(x,y,z)), ans)
1558015597
test(2060.157, x, ans) # setcoalesce updated the first item (x) by reference
15598+
# nan parameter, #4567
15599+
test(2060.158, fcoalesce(c(NA_real_, NaN), 0, nan=NA), c(0, 0))
15600+
test(2060.159, fcoalesce(c(NA_real_, NaN), 0, nan=NaN), c(0, NaN))
15601+
test(2060.160, fcoalesce(c(NA_real_, NaN), c(1, 2), nan=NA), c(1, 2))
15602+
test(2060.161, fcoalesce(c(NA_real_, NaN), c(1, 2), nan=NaN), c(1, NaN))
1558115603
# factor of different levels
1558215604
x = factor(c('a','b',NA,NA,'b'))
1558315605
y = factor(c('b','b','a',NA,'b'))
@@ -21536,3 +21558,11 @@ f = tempfile()
2153621558
writeLines(c('a', rep('0x1.ffffp0', 10000L), '0x1.ff\x9fp0', rep('0x1.ffffp0', 20000L)), f)
2153721559
test(2334, names(fread(f)), "a")
2153821560
unlink(f)
21561+
21562+
# Tests for new isoyear() helper (complement to isoweek) #7154
21563+
test(2335.1, isoyear(as.IDate("2019-12-30")), 2020L) # End of year edge case
21564+
test(2335.2, isoyear(as.IDate("2016-01-01")), 2015L) # Start of year edge case
21565+
test(2335.3, isoyear(as.IDate("2023-08-15")), 2023L) # Normal mid-year case
21566+
test(2335.4, isoyear(as.IDate(c("2019-12-30", "2016-01-01", "2023-08-15"))),c(2020L, 2015L, 2023L))
21567+
test(2335.5, isoyear("2019-12-30"), 2020L)
21568+
test(2335.6, isoyear(as.Date("2019-12-30")), 2020L)

man/IDateTime.Rd

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
\alias{mday}
3939
\alias{week}
4040
\alias{isoweek}
41+
\alias{isoyear}
4142
\alias{month}
4243
\alias{quarter}
4344
\alias{year}
@@ -92,6 +93,7 @@ wday(x)
9293
mday(x)
9394
week(x)
9495
isoweek(x)
96+
isoyear(x)
9597
month(x)
9698
quarter(x)
9799
year(x)
@@ -187,6 +189,8 @@ which specify that the first week of the year is the one containing the first Th
187189
This convention ensures that week boundaries align consistently with year boundaries,
188190
accounting for both year transitions and varying day counts per week.
189191
192+
Similarly, \code{isoyear()} returns the ISO 8601 year corresponding to the ISO week.
193+
190194
}
191195
192196
\value{
@@ -200,7 +204,7 @@ accounting for both year transitions and varying day counts per week.
200204
\code{itime} in \code{IDate} and \code{ITime} format.
201205
202206
\code{second}, \code{minute}, \code{hour}, \code{yday}, \code{wday},
203-
\code{mday}, \code{week}, \code{month}, \code{quarter},
207+
\code{mday}, \code{week}, \code{isoweek}, \code{isoyear}, \code{month}, \code{quarter},
204208
and \code{year} return integer values
205209
for second, minute, hour, day of year, day of week,
206210
day of month, week, month, quarter, and year, respectively.
@@ -281,6 +285,17 @@ round(seqdates, "months")
281285
round(seqtimes, "hours")
282286
trunc(seqtimes, "hours")
283287

288+
# Examples for isoyear() and isoweek()
289+
d1 = as.IDate("2019-12-30")
290+
year(d1)
291+
isoweek(d1)
292+
isoyear(d1)
293+
294+
d2 = as.IDate("2016-01-01")
295+
year(d2)
296+
isoweek(d2)
297+
isoyear(d2)
298+
284299
}
285300
\keyword{utilities}
286301

0 commit comments

Comments
 (0)