[R] removing values from a vector, where both the value and its name are the same?
Marc Schwartz
marc_schwartz at comcast.net
Fri Jun 15 20:49:45 CEST 2007
On Fri, 2007-06-15 at 11:19 -0700, new ruser wrote:
> I have an array such as:
>
> x=c(sum=77, min=4,max=9, count=5, min=4,max=9, count=8 , test=77)
>
> I wish to remove values where both the name and the value are identical.
>
> eg. i wish to end up with:
> x2=c(sum=77, min=4,max=9, count=5, count=8, test=77)
>
> What is the "best" way to do this?
Not sure if this is the best way, but since you need to compare both the
values and their name attributes for 'uniqueness':
> x[!(duplicated(x) & duplicated(names(x)))]
sum min max count count test
77 4 9 5 8 77
What is being done is to first compare the values for duplicates. Note
that the second value is identified as the duplicate, not the first:
> duplicated(x)
[1] FALSE FALSE FALSE FALSE TRUE TRUE FALSE TRUE
and then compare the names for duplicates:
> duplicated(names(x))
[1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE
Then compare the two logical vectors and get the indices where BOTH are
TRUE:
> (duplicated(x) & duplicated(names(x)))
[1] FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE
Now, negate the relation:
> !(duplicated(x) & duplicated(names(x)))
[1] TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE
and return the values in 'x' that satisfy the logical indices:
> x[!(duplicated(x) & duplicated(names(x)))]
sum min max count count test
77 4 9 5 8 77
See ?duplicated. You might also want to look
at ?unique, ?identical, ?all.equal and ?isTRUE.
Note that the above example will likely fail if any of the values are
floats:
> duplicated(c(0.5 - 0.4, 0.1))
[1] FALSE FALSE
in which case, you would need to use a looping structure where the value
comparisons use isTrue(all.equal(...)) instead.
HTH,
Marc Schwartz
More information about the R-help
mailing list