[R] Removing elements ..., NO bug in which() function
Henrik Bengtsson
hb at biostat.ucsf.edu
Thu Feb 24 05:23:08 CET 2011
On Wed, Feb 23, 2011 at 1:02 PM, Martin Maechler
<maechler at stat.math.ethz.ch> wrote:
>>>>>> "RK" == Rumen Kostadinov <rkostadi at gmail.com>
>>>>>> on Sun, 13 Feb 2011 12:46:52 -0500 writes:
>
> RK> Thanks Sarah,
> RK> Yes, the function behaves Exactly as documented:
>
> RK> check this out:
> >> a = c(1,2,3,4,5)
> >> a[which(a!=6)]
> RK> [1] 1 2 3 4 5
> >> a[!which(a==6)]
> RK> numeric(0)
> >> a[-which(a==6)]
> RK> numeric(0)
> >> a[!a==6]
> RK> [1] 1 2 3 4 5
>
> RK> I guess this is just a "gotcha", since
> RK> I often use !which and -which to remove elements,
> RK> So one should use
> RK> a[which(a!=stuff to remove)]
> RK> instead of
> RK> a[-which(a==stuff to remove)]
> RK> a[!which(a==stuff to remove)]
>
> BTW: you have just seen why you should *NOT* use
> a[ -which() ]
>
> and probably should use which() much less than you currently do.
> Some useRs seem overly fond of which() instead of working with
> the logical vectors directly ...
> {{Yes, I know that in some situations which() "works with NAs"...}}
>
> I think we (R-core) should get back to Bill Dunlap's suggestions
> on the R-devel list and think of providing fast functions for
> things like "L && !is.na(L)"
> ...
> in other words, versions of the utilities I have in (the R
> package) Matrix/R/Auxiliaries.R,
>
> ## Need to consider NAs ; "== 0" even works for logical & complex:
> ## Note that "!x" is faster than "x == 0", but does not (yet!) work for complex
> ## if we did these in C, would gain a factor 2 (or so):
> is0 <- function(x) !is.na(x) & x == 0
> isN0 <- function(x) is.na(x) | x != 0
> is1 <- function(x) !is.na(x) & x # also == "isTRUE componentwise"
>
> ##
> all0 <- function(x) !any(is.na(x)) && all(!x) ## ~= allFalse
> any0 <- function(x) isTRUE(any(x == 0)) ## ~= anyFalse
> ## These work "identically" for 1 ('==' TRUE) and 0 ('==' FALSE)
> ## (but give a warning for "double" 1 or 0)
> ## TODO: C versions of these would be faster
> allTrue <- function(x) all(x) && !any(is.na(x))
> allFalse <- function(x) !any(x) && !any(is.na(x))## ~= all0
> anyFalse <- function(x) isTRUE(any(!x)) ## ~= any0
>
>
> Note that I comment twice that it would be nice to have fast
> versions of these (via C).
Well, at least for any(is.na(x)) there is a fast ("early stopping")
implementation in anyMissing(x) of the 'matrixStats' package (also in
Biobase of Bioconductor). As the author I say: feel free to include
it in "base" R. Code is available at:
https://r-forge.r-project.org/scm/viewvc.php/pkg/matrixStats/?root=matrixstats
See files R/anyMissing.R and src/anyMissing.c
At least a start.
/Henrik
>
> Martin
>
>
>
> RK> On Sun, Feb 13, 2011 at 12:37 PM, Sarah Goslee
> <sarah.goslee at gmail.com> wrote:
> >> If by "bug" you mean "function behaving exactly as documented."
> >>
> >> which() returns only the matches, the TRUE values. If there are
> >> no matches, it doesn't return anything.
> >>
> >> If I understand what you are trying to do, and I may not,
> >> a[which(a != 5)] is really what you want, and it is precisely
> >> to preserve that behavior that which() does what it does.
> >>
> >> Sarah
> >>
> >> ---
> >>
> >> which package:base R
> >> Documentation
> >>
> >> Description:
> >>
> >> Give the ‘TRUE’ indices of a logical object, allowing for
> >> array indices.
> >>
> >> Value:
> >>
> >> If ‘arr.ind == FALSE’ (the default), an integer vector with
> >> ‘length’ equal to ‘sum(x)’, i.e., to the number of ‘TRUE’s
> >> in ‘x’; Basically, the result is ‘(1:length(x))[x]’.
> >>
> >> ---
> >> On Sun, Feb 13, 2011 at 11:59 AM, Rumen Kostadinov
> >> <rkostadi at gmail.com> wrote:
> >>> Dear all,
> >>>
> >>> I found a bug in the which() function.
> >>>
> >>> When trying to remove elements with the which function, if the
> >>> criteria is not matched, numeric(0) is returned instead of the
> >>> array itself.
> >>>
> >>> This is very weird.
> >>>
> >>>> a = c(1,2,3,4,5)
> >>>> a[!a==6]
> >>> [1] 1 2 3 4 5
> >>>> a[-which(a==6)]
> >>> numeric(0)
> >>>> a[-which(a==5)]
> >>> [1] 1 2 3 4
> >>>> a[!a==5]
> >>> [1] 1 2 3 4
> >>>
> >>> Is this correct? I believe this is a bug.
> >>>
> >>> I have to rewrite a lot of my R code to use
> >>> a = a[!criteria]
> >>> and not
> >>> a = a[-which(criteria)]
> >>>
> >>> R.
> >>>
> >>
> >>
> >> --
> >> Sarah Goslee
> >> http://www.functionaldiversity.org
> >>
>
> RK> ______________________________________________ RK>
> R-help at r-project.org mailing list RK>
> https://stat.ethz.ch/mailman/listinfo/r-help RK> PLEASE do read
> the posting guide http://www.R-project.org/posting-guide.html RK>
> and provide commented, minimal, self-contained, reproducible code.
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
More information about the R-help
mailing list