Skip to content

Commit c446f2e

Browse files
droplevels works on 0-row tables (#7131)
* droplevels works on 0-row tables * another test: don't interfere with non-factor columns
1 parent 35544d3 commit c446f2e

File tree

3 files changed

+10
-1
lines changed

3 files changed

+10
-1
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21358,3 +21358,10 @@ test(2327.1, cube(DT, .(min(value)), "var"),
2135821358
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")
21361+
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()))

0 commit comments

Comments
 (0)