Hi all, I'm a little surprised at > NULL == c("a", "b") logical(0) > all(NULL == c("a", "b")) [1] TRUE Reading the documentation for all() this was not clear for me to be expected. Originally the question came up when using > match.arg(NULL, c("a", "b")) [1] "a" where I had thought an error would occur. So could someone please help me and explain what I have overlooked. Should I realy have to use is.null() as a precondition check here when a NULL argument could arise. Regards, Matthias PS: the same behaviour occurs in R 1.9.1 and R 2.1.0 devel: 2005-02-07 > version _ platform i686-pc-linux-gnu arch i686 os linux-gnu system i686, linux-gnu status major 2 minor 0.1 year 2004 month 11 day 15 language R -- Matthias Burger Project Manager/ Biostatistician Epigenomics AG Kleine Praesidentenstr. 1 10178 Berlin, Germany phone:+49-30-24345-371 fax:+49-30-24345-555 http://www.epigenomics.com matthias.burger at epigenomics.com
Matthias Burger <matthias.burger at epigenomics.com> writes:> Hi all, > > I'm a little surprised at > > NULL == c("a", "b") > logical(0) > > all(NULL == c("a", "b")) > [1] TRUE > > Reading the documentation for all() this was not clear for me to be expected.all() over a vector of length zero is TRUE for much the same reason that prod(numeric(0)) is 1 which in turn is related to sums over empty sets being zero. NULL has length zero so comparisons with it makes a logical vector of length zero....> Originally the question came up when using > > match.arg(NULL, c("a", "b")) > [1] "a" > where I had thought an error would occur. > > So could someone please help me and explain what I have overlooked. > Should I realy have to use is.null() as a precondition check here when a NULL > argument could arise. >Probably yes, unless you happen to like that behaviour (not entirely unlikely in some cases). -- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
On Wed, 9 Feb 2005, Matthias Burger wrote:> I'm a little surprised at >> NULL == c("a", "b") > logical(0)NULL is of length 0. == coerces arguments and recycles as required, so you have done as.character(NULL) == character(0)>> all(NULL == c("a", "b")) > [1] TRUE > > Reading the documentation for all() this was not clear for me to be expected.all() of a zero-length vector is obviously true as all (zero) elements are true, standard in logic.> Originally the question came up when using >> match.arg(NULL, c("a", "b")) > [1] "a" > where I had thought an error would occur.Did you read the help page? You have misused the function (the first argument should be a character string), and it does not say what it does in the case of this particular misuse. This behaviour is different from S, which also does not say.> So could someone please help me and explain what I have overlooked. > Should I realy have to use is.null() as a precondition check here when a NULL > argument could arise.Yes, as the help page says `character string' and NULL is not a character string. The user should ensure the input is as documented. [I suspect BTW that this undocumented behaviour is intentional, but it was introduced in about June 1998 and I cannot find a comment at that time.] -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
On Wed, 9 Feb 2005, Matthias Burger wrote:> > Hi all, > > I'm a little surprised at >> NULL == c("a", "b") > logical(0) >> all(NULL == c("a", "b")) > [1] TRUE > > Reading the documentation for all() this was not clear for me to be expected.This is related to the question about sum(numeric(0)) that came up a few days ago. It is conventional in logic that "for all x in X: P(x)" is true when X is empty. A reason why this is a useful convention is that it implies all(c(x,y)) == all(x) && all(y) is still true when x or y happens to be empty. The converse holds for any(): any(logical(0)) is FALSE. This surprises fewer people. A fairly complete list is all(NULL) is TRUE any(NULL) is FALSE sum(NULL) is 0 prod(NULL) is 1 min(NULL) is Inf max(NULL) is -Inf with the last two giving a warning> Originally the question came up when using >> match.arg(NULL, c("a", "b")) > [1] "a" > where I had thought an error would occur.I would have assumed "a" would be returned, thinking of match.arg as a way to handle default arguments, but I agree it isn't documented, and looking at the code it isn't clear what the author thought. On the other hand, it *is* documented that `arg' must be a character string, and NULL isn't a character string. Perhaps you should just use pmatch() directly, as the main advantage of match.arg() is its ability to look up default arguments, which you don't seem to be using. -thomas