FIX for old and new problems with order(): order fails with na.last=NA (PR#1981)

oehl_list@gmx.de oehl_list@gmx.de
Tue, 3 Sep 2002 21:13:55 +0200 (MET DST)


I recently reported order() to ignore decreasing=TRUE with na.last=NA.
Now I discovered two other problems and send corrected code.

Best regards


Jens Oehlschlägel


# PROBLEM 1 see PR#1906


# PROBLEM 2
> order(1, na.last=NA)
Error in apply(sapply(z, is.na), 1, any) : 
        dim(X) must have a positive length
# clearly wrong as
> order(1)
[1] 1
# is defined


# PROBLEM 3
> order(c(NA, NA), na.last=NA)
Error in order(c(NA, NA), na.last = NA) : all elements contain an NA
# The help file promises ordering indices to all non-NA elements. 
# Thus, if all elements are NA, consequently the result should be integer(0)
# The prototype also returns integer(0) and additionally gives a warning
from sort.list()


# Here are fixes for all three problems

# save old version for comparision below
old.order <- order  


order <- function (..., na.last = TRUE, decreasing = FALSE)
{
    if (!is.na(na.last)) 
        .Internal(order(na.last, decreasing, ...))
    else {
        z <- list(...)
        if (any(diff(sapply(z, length)) != 0)) 
            stop("Argument lengths differ")
        ok <- !apply(matrix(sapply(z, is.na), nrow=length(z[[1]]),
ncol=length(z)), 1, any)  # make shure the result of sapply is a matrix
        if (all(!ok)){
            # stop("all elements contain an NA")	# don't turn all-NA into a
stop error
            return(integer(0))				# don't turn all-NA into a stop error
        }
        z[[1]][!ok] <- NA
        z[["decreasing"]] <- decreasing  		# put decreasing= into parameters
passed to next call of order
        ans <- do.call("order", z)
        keep <- seq(length = sum(ok))  			# simplify and (theoretical) speed
up
        ans[keep]					# simplify and (theoretical) speed up
    }
}

x1 <- rep(1, 3)
x2 <- c(1, NA, 2)
order(x1, x2)
old.order(x1, x2)
order(x1, x2, decreasing=TRUE)
old.order(x1, x2, decreasing=TRUE)
order(x1, x2, na.last=FALSE)
old.order(x1, x2, na.last=FALSE)
order(x1, x2, decreasing=TRUE, na.last=FALSE)
old.order(x1, x2, decreasing=TRUE, na.last=FALSE)
order(x1, x2, na.last=NA)
old.order(x1, x2, na.last=NA)
order(x1, x2, decreasing=TRUE, na.last=NA)
old.order(x1, x2, decreasing=TRUE, na.last=NA)

order(1, na.last=NA)
old.order(1, na.last=NA)

order(c(NA, NA), na.last=NA)
old.order(c(NA, NA), na.last=NA)



# results

> x1 <- rep(1, 3)
> x2 <- c(1, NA, 2)
> order(x1, x2)
[1] 1 3 2
> old.order(x1, x2)
[1] 1 3 2
> order(x1, x2, decreasing=TRUE)
[1] 3 1 2
> old.order(x1, x2, decreasing=TRUE)
[1] 3 1 2
> order(x1, x2, na.last=FALSE)
[1] 2 1 3
> old.order(x1, x2, na.last=FALSE)
[1] 2 1 3
> order(x1, x2, decreasing=TRUE, na.last=FALSE)
[1] 2 3 1
> old.order(x1, x2, decreasing=TRUE, na.last=FALSE)
[1] 2 3 1
> order(x1, x2, na.last=NA)
[1] 1 3
> old.order(x1, x2, na.last=NA)
[1] 1 3
> order(x1, x2, decreasing=TRUE, na.last=NA)
[1] 3 1
> old.order(x1, x2, decreasing=TRUE, na.last=NA)
[1] 1 3
> 
> order(1, na.last=NA)
[1] 1
> old.order(1, na.last=NA)
Error in apply(sapply(z, is.na), 1, any) : 
        dim(X) must have a positive length
> 
> order(c(NA, NA), na.last=NA)
numeric(0)
> old.order(c(NA, NA), na.last=NA)
Error in old.order(c(NA, NA), na.last = NA) : 
        all elements contain an NA



> version
         _              
platform i386-pc-mingw32
arch     i386           
os       Win32          
system   i386, mingw32  
status                  
major    1              
minor    5.1            
year     2002           
month    06             
day      17             
language R  

-- 
GMX - Die Kommunikationsplattform im Internet.
http://www.gmx.net


-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._