Skip to content

Commit 821e5a0

Browse files
committed
Merge branch 'master' of https://github.com/Rdatatable/data.table into issue_6882
2 parents e78b966 + 038e7f8 commit 821e5a0

21 files changed

+298
-264
lines changed

.ci/linters/md/news_linter.R renamed to .ci/linters/md/news_github_link_mismatch_linter.R

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,6 @@
1-
# ensure that numbered list in each section is in sequence
2-
check_section_numbering = function(news) {
3-
if (!grepl("NEWS", news)) return(invisible())
4-
news = readLines(news)
5-
# plain '#' catches some examples; 'd' for 'data.table'
6-
sections = grep("^#+ [A-Zd]", news)
7-
entries = grep("^[0-9]+[.]", news)
8-
entry_value = as.integer(gsub("^([0-9]+)[.].*", "\\1", news[entries]))
9-
section_id = findInterval(entries, sections)
10-
11-
any_mismatch = FALSE
12-
for (id in unique(section_id)) {
13-
section_entries = entry_value[section_id == id]
14-
intended_value = seq_along(section_entries)
15-
matched = section_entries == intended_value
16-
if (all(matched)) next
17-
any_mismatch = TRUE
18-
section_header = news[sections[id]]
19-
cat(sprintf(
20-
"In section '%s' (line %d), bad numbering:\n%s\n",
21-
section_header, sections[id],
22-
paste0(" [", section_entries[!matched], " --> ", intended_value[!matched], "]", collapse="\n")
23-
))
24-
}
25-
stopifnot("Please fix the NEWS issues above" = !any_mismatch)
26-
}
27-
281
# ensure that GitHub link text & URL actually agree
29-
check_gh_links = function(news) {
2+
news_github_link_mismatch_linter = function(news) {
3+
if (!grepl("NEWS", news)) return(invisible())
304
news = readLines(news)
315
gh_links_info = gregexpr(
326
"\\[#(?<md_number>[0-9]+)\\]\\(https://github.com/Rdatatable/data.table/(?<link_type>[^/]+)/(?<link_number>[0-9]+)\\)",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# ensure that numbered list in each section is in sequence
2+
news_section_numbering_linter = function(news) {
3+
if (!grepl("NEWS", news)) return(invisible())
4+
news = readLines(news)
5+
# plain '#' catches some examples; 'd' for 'data.table'
6+
sections = grep("^#+ [A-Zd]", news)
7+
entries = grep("^[0-9]+[.]", news)
8+
entry_value = as.integer(gsub("^([0-9]+)[.].*", "\\1", news[entries]))
9+
section_id = findInterval(entries, sections)
10+
11+
any_mismatch = FALSE
12+
for (id in unique(section_id)) {
13+
section_entries = entry_value[section_id == id]
14+
intended_value = seq_along(section_entries)
15+
matched = section_entries == intended_value
16+
if (all(matched)) next
17+
any_mismatch = TRUE
18+
section_header = news[sections[id]]
19+
cat(sprintf(
20+
"In section '%s' (line %d), bad numbering:\n%s\n",
21+
section_header, sections[id],
22+
paste0(" [", section_entries[!matched], " --> ", intended_value[!matched], "]", collapse="\n")
23+
))
24+
}
25+
stopifnot("Please fix the NEWS issues above" = !any_mismatch)
26+
}

.ci/linters/md/heading_id_linter.R renamed to .ci/linters/md/vignette_heading_id_linter.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ensure that ids are limited to alphanumerics and dashes
22
# (in particular, dots and underscores break the links)
3-
check_header_ids = function(md) {
3+
vignette_heading_id_linter = function(md) {
44
if (!grepl('[.]Rmd$', md)) return(invisible())
55
md = readLines(md)
66
# A bit surprisingly, some headings don't start with a letter.

.ci/linters/rd/backtick_linter.R

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# ensure no markdown-style backticks wind up in Rd where \code is intended
2+
options_documentation_linter = function(rd_file) {
3+
rd = tools::parse_Rd(rd_file)
4+
5+
error_if_backtick = function(rd_obj) {
6+
if (!is.recursive(rd_obj)) {
7+
if (any(grepl("`", rd_obj, fixed=TRUE))) {
8+
stop(sprintf(
9+
"Rd is not markdown -- backticks (`) don't render as code! Use \\code{...}.\nObserved in string '%s' in file %s",
10+
trimws(rd_obj), rd_file
11+
))
12+
}
13+
return(invisible())
14+
}
15+
tags = vapply(rd_obj, \(x) attr(x, "Rd_tag") %||% "", FUN.VALUE="")
16+
# backtick is valid inside R code (e.g. \examples, \code, \preformatted)
17+
rd_obj = rd_obj[!tags %in% c("RCODE", "VERB")]
18+
lapply(rd_obj, error_if_backtick)
19+
}
20+
21+
invisible(error_if_backtick(rd))
22+
}
File renamed without changes.

GOVERNANCE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Functionality that is out of current scope:
6363
## Committer
6464

6565
* Definition: permission to commit to, and merge PRs into, master branch.
66-
* How to obtain this role: after a Reviewer has a consistent history of careful reviews of others' PRs, then a current Committer should ask all other current Committers if they approve promoting the Reviewer to Committer, and it should be done if there is Consensus among active Committers.
66+
* How to obtain this role: after a Reviewer has a consistent history of careful reviews of others' substantial PRs, then a current Committer should ask all other current Committers if they approve promoting the Reviewer to Committer, and it should be done if there is Consensus among active Committers.
6767
* How this role is recognized: credited via role="aut" in DESCRIPTION (so they appear in Author list on CRAN), and added to https://github.com/orgs/Rdatatable/teams/committers which gives permission to merge PRs into master branch.
6868

6969
## CRAN Maintainer
@@ -139,6 +139,8 @@ data.table Version line in DESCRIPTION typically has the following meanings
139139

140140
# Governance history
141141

142+
July 2025: require potential new committers' considered history to be of "substantial" PRs
143+
142144
May 2025: update Finance and CoC language for NumFOCUS incorporation.
143145

144146
Feb 2025: add Finances and Funding section, update Code of Conduct section to be a brief summary and reference the broader CoC document.

NEWS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
# 2: 2 6 4 5
4141
```
4242

43-
8. `groupingsets()` gets a new argument `enclos` for use together with the `jj` argument in functions wrapping `groupingsets()`, including the existing wrappers `rollup()` and `cube()`. When forwarding a `j`-expression as `groupingsets(jj = substitute(j))`, make sure to pass `enclos = parent.frame()` as well, so that the `j`-expression will be evaluated in the right context. This makes it possible for `j` to refer to variables outside the `data.table`.
43+
8. `groupingsets()` gets a new argument `enclos` for use together with the `jj` argument in functions wrapping `groupingsets()`, including the existing wrappers `rollup()` and `cube()`, [#5560](https://github.com/Rdatatable/data.table/issues/5560). When forwarding a `j`-expression as `groupingsets(jj = substitute(j))`, make sure to pass `enclos = parent.frame()` as well, so that the `j`-expression will be evaluated in the right context. This makes it possible for `j` to refer to variables outside the `data.table`. Thanks @sindribaldur for the report and @aitap for the fix.
4444

4545
### BUG FIXES
4646

@@ -82,6 +82,8 @@
8282
8383
19. 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.
8484
85+
20. `droplevels()` works on 0-row data.tables, [#7043](https://github.com/Rdatatable/data.table/issues/7043). The result will have factor columns `factor(character())`, consistent with the data.frame method. Thanks @advieser for the report and @MichaelChirico for the fix.
86+
8587
### NOTES
8688
8789
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/.

R/fdroplevels.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# 647 fast droplevels.data.table method
22
fdroplevels = function(x, exclude = if (anyNA(levels(x))) NULL else NA, ...) {
33
stopifnot(inherits(x, "factor"))
4+
if (!length(x)) return(structure(integer(), class='factor', levels=character())) # skip factor() overhead
45
lev = which(tabulate(x, nlevels(x)) & (!match(levels(x), exclude, 0L)))
56
ans = match(as.integer(x), lev)
67
setattr(ans, 'levels', levels(x)[lev])
@@ -15,7 +16,6 @@ droplevels.data.table = function(x, except=NULL, exclude, ...){
1516
}
1617

1718
setdroplevels = function(x, except=NULL, exclude=NULL) {
18-
if (!nrow(x)) return(invisible(x))
1919
ix = vapply_1b(x, is.factor)
2020
if (!is.null(except)) {
2121
stopifnot(is.numeric(except), except >= 1L, except <= length(x))

inst/tests/tests.Rraw

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21359,10 +21359,17 @@ test(2327.2, cube(DT, .(as.numeric(base::min(value, na.rm=TRUE))), "var"),
2135921359
data.table(var = c("a", "b", "c", "d", NA), V1 = c(1.0, 2.0, 3.0, Inf, 1.0)),
2136021360
warning="no non-missing arguments to min")
2136121361

21362+
# droplevels should still work on a 0-row table, #7043
21363+
DT = data.table(f=factor(character(), levels='a'))
21364+
test(2328.1, levels(droplevels(DT)$f), character())
21365+
DT[, i := integer()]
21366+
DT[, f2 := factor()]
21367+
test(2328.2, droplevels(DT), data.table(f=factor(), i=integer(), f2=factor()))
21368+
2136221369
#6882 print() output with col.names="none"
2136321370
dt = data.table(short = 1:3, verylongcolumnname = 4:6)
21364-
test(2328.1, print(dt, col.names = "none"), output = "1: 1 4\n2: 2 5\n3: 3 6\n")
21371+
test(2329.1, print(dt, col.names = "none"), output = "1: 1 4\n2: 2 5\n3: 3 6\n")
2136521372
dt = data.table(x = 123456, y = "wide_string")
21366-
test(2328.2, print(dt, col.names = "none"), output = "1: 123456 wide_string\n")
21373+
test(2329.2, print(dt, col.names = "none"), output = "1: 123456 wide_string\n")
2136721374
dt = data.table(a = NA_integer_, b = NaN)
21368-
test(2328.3, print(dt, col.names = "none"), output = "1: NA NaN\n")
21375+
test(2329.3, print(dt, col.names = "none"), output = "1: NA NaN\n")

man/IDateTime.Rd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ accounting for both year transitions and varying day counts per week.
205205
for second, minute, hour, day of year, day of week,
206206
day of month, week, month, quarter, and year, respectively.
207207
\code{yearmon} and \code{yearqtr} return double values representing
208-
respectively `year + (month-1) / 12` and `year + (quarter-1) / 4`.
208+
respectively \code{year + (month-1) / 12} and \code{year + (quarter-1) / 4}.
209209
210210
\code{second}, \code{minute}, \code{hour} are taken directly from
211211
the \code{POSIXlt} representation.
@@ -217,7 +217,7 @@ accounting for both year transitions and varying day counts per week.
217217
}
218218
\references{
219219
220-
G. Grothendieck and T. Petzoldt, ``Date and Time Classes in R,''
220+
G. Grothendieck and T. Petzoldt, \dQuote{Date and Time Classes in R},
221221
R News, vol. 4, no. 1, June 2004.
222222
223223
H. Wickham, https://gist.github.com/hadley/10238.

0 commit comments

Comments
 (0)