[R] Removing elements ..., NO bug in which() function
Martin Maechler
maechler at stat.math.ethz.ch
Wed Feb 23 22:02:14 CET 2011
>>>>> "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).
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.
More information about the R-help
mailing list