Skip to content

Commit 6485a7a

Browse files
Implement a fix
1 parent 6cd69f0 commit 6485a7a

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

R/data.table.R

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,7 +1526,6 @@ replace_dot_alias = function(e) {
15261526
if (length(byval) && length(byval[[1L]])) {
15271527
if (!bysameorder && isFALSE(byindex)) {
15281528
if (verbose) {last.started.at=proc.time();catf("Finding groups using forderv ... ");flush.console()}
1529-
browser()
15301529
o__ = forderv(byval, sort=keyby, retGrp=TRUE)
15311530
# The sort= argument is called sortGroups at C level. It's primarily for saving the sort of unique strings at
15321531
# C level for efficiency when by= not keyby=. Other types also retain appearance order, but at byte level to
@@ -2013,8 +2012,8 @@ replace_dot_alias = function(e) {
20132012
if (verbose) {last.started.at=proc.time();catf("setkey() afterwards for keyby=.EACHI ... ");flush.console()}
20142013
setkeyv(ans,names(ans)[seq_along(byval)])
20152014
if (verbose) {cat(timetaken(last.started.at),"\n"); flush.console()}
2016-
} else if (keyby || (haskey(x) && bysameorder && (byjoin || (length(allbyvars) && identical(allbyvars,head(key(x),length(allbyvars))))))) {
2017-
setattr(ans,"sorted",names(ans)[seq_along(grpcols)])
2015+
} else if (.by_result_is_keyable(x, keyby, bysameorder, byjoin, allbyvars, bysub)) {
2016+
setattr(ans, "sorted", names(ans)[seq_along(grpcols)])
20182017
}
20192018
setalloccol(ans) # TODO: overallocate in dogroups in the first place and remove this line
20202019
}
@@ -3042,6 +3041,21 @@ rleidv = function(x, cols=seq_along(x), prefix=NULL) {
30423041
ids
30433042
}
30443043

3044+
.by_result_is_keyable = function(x, keyby, bysameorder, byjoin, byvars, bysub) {
3045+
if (keyby) return(TRUE)
3046+
k = key(x)
3047+
if (is.null(k)) return(FALSE) # haskey(x) but saving 'k' for below
3048+
if (!bysameorder) return(FALSE)
3049+
if (byjoin) return(TRUE)
3050+
if (!length(byvars)) return(FALSE)
3051+
if (!identical(byvars, head(k, length(byvars)))) return(FALSE) # match key exactly, in order
3052+
# For #5583, we also ensure there are no function calls in by (which might break sortedness)
3053+
if (is.name(bysub)) return(TRUE)
3054+
if (identical(bysub[[1L]], quote(list))) bysub = bysub[-1L]
3055+
if (length(all.names(bysub)) > length(byvars)) return(FALSE)
3056+
return(TRUE)
3057+
}
3058+
30453059
.is_withFALSE_range = function(e, x, root=root_name(e), vars=all.vars(e)) {
30463060
if (root != ":") return(FALSE)
30473061
if (!length(vars)) return(TRUE) # e.g. 1:10

0 commit comments

Comments
 (0)