diff --git a/doc/NEWS.Rd b/doc/NEWS.Rd index 6495a15078..df0043973a 100644 --- a/doc/NEWS.Rd +++ b/doc/NEWS.Rd @@ -330,7 +330,13 @@ including two patch proposals by Brodie Gaslam. \item \code{qnorm(, log.p=TRUE)} is now correct - to at least five digits where it was catastrophically wrong, previously. + to at least five digits where it was catastrophically wrong, + previously. + + \item \code{sum(df)} and similar \code{"Summary"}- and + \code{"Math"}-group member functions now work for data frames + \code{df} with \code{\link{logical}} columns, notably also of zero + rows. Reported to R-devel by Martin "b706". } } } diff --git a/src/library/base/R/dataframe.R b/src/library/base/R/dataframe.R index 13749852a6..e83bd4561e 100644 --- a/src/library/base/R/dataframe.R +++ b/src/library/base/R/dataframe.R @@ -1606,14 +1606,15 @@ as.matrix.data.frame <- function (x, rownames.force = NA, ...) Math.data.frame <- function (x, ...) { - mode.ok <- vapply(x, function(x) is.numeric(x) || is.complex(x), NA) + mode.ok <- vapply(x, function(x) + is.numeric(x) || is.logical(x) || is.complex(x), NA) if (all(mode.ok)) { x[] <- lapply(X = x, FUN = .Generic, ...) return(x) } else { vnames <- names(x) if (is.null(vnames)) vnames <- seq_along(x) - stop("non-numeric variable(s) in data frame: ", + stop("non-numeric-alike variable(s) in data frame: ", paste(vnames[!mode.ok], collapse = ", ")) } } @@ -1699,8 +1700,8 @@ Summary.data.frame <- function(..., na.rm) args <- list(...) args <- lapply(args, function(x) { x <- as.matrix(x) - if(!is.numeric(x) && !is.complex(x)) - stop("only defined on a data frame with all numeric variables") + if(!is.numeric(x) && !is.logical(x) && !is.complex(x)) + stop("only defined on a data frame with all numeric-alike variables") x }) do.call(.Generic, c(args, na.rm=na.rm)) diff --git a/src/library/base/man/groupGeneric.Rd b/src/library/base/man/groupGeneric.Rd index a3543a1b34..e8f99c1589 100644 --- a/src/library/base/man/groupGeneric.Rd +++ b/src/library/base/man/groupGeneric.Rd @@ -1,6 +1,6 @@ % File src/library/base/man/groupGeneric.Rd % Part of the R package, https://www.R-project.org -% Copyright 1995-2017 R Core Team +% Copyright 1995-2020 R Core Team % Distributed under GPL 2 or later \name{groupGeneric} @@ -139,6 +139,11 @@ } Members of this group dispatch on the first argument supplied. + Note that the \code{\link{data.frame}} methods for the + \code{"Summary"} and \code{"Math"} groups require \dQuote{numeric-alike} + columns \code{x}, i.e., fulfilling \preformatted{ + is.numeric(x) || is.logical(x) || is.complex(x)} + \item Group \code{"Complex"}: \itemize{ \item \code{Arg}, \code{Conj}, \code{Im}, \code{Mod}, \code{Re} diff --git a/tests/reg-tests-1d.R b/tests/reg-tests-1d.R index e406735d04..26f15a46f7 100644 --- a/tests/reg-tests-1d.R +++ b/tests/reg-tests-1d.R @@ -4553,6 +4553,24 @@ options(op) ## had worked up to R 3.6.3, but not from 4.0.0 to 4.0.3 +## Summary() and Math() data.frame methods with *logical* columns +a <- na.omit(airquality) +aF <- a[FALSE,] # 0-row version of it +dL0 <- data.frame(x=numeric(), L=logical()) # logical column +stopifnot(exprs = { + ## "Summary" : + sum(aF) == 0 # gave Error "only defined on a data frame with all numeric variables" + sum(subset(a, Ozone > 200)) == 0 # (ditto) + suppressWarnings(range(dL0) == c(Inf, -Inf)) # (2 warnings) + ## "Math" , gave Error..: non-numeric variable(s) in data frame : + identical(exp(data.frame(L=TRUE)), data.frame(L=exp(TRUE))) + identical(sinL0 <- sin(dL0), data.frame(x=numeric(), L=numeric())) + identical(sinL0, log1p(dL0)) + identical(cumsum(dL0), data.frame(x=numeric(), L=integer())) +}) +## probably never worked in any R <= 4.0.3 + + ## keep at end rbind(last = proc.time() - .pt,