Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

subset() drops attributes on vectors; how to maintain/persist them?

Let's say I have a vector where I've set a few attributes:

vec <- sample(50:100,1000, replace=TRUE)
attr(vec, "someattr") <- "Hello World"

When I subset the vector, the attributes are dropped. For example:

tmp.vec <- vec[which(vec > 80)]
attributes(tmp.vec) # Now NULL

Is there a way to, subset and persist attributes without having to save them to another temporary object?

Bonus: Where would one find documentation of this behaviour?

like image 839
Brandon Bertelsen Avatar asked Feb 28 '12 17:02

Brandon Bertelsen


1 Answers

I would write a method for [ or subset() (depending on how you are subsetting) and arrange for that to preserve the attributes. That would need a "class" attribute also adding to your vector so that dispatch occurs.

vec <- 1:10
attr(vec, "someattr") <- "Hello World"
class(vec) <- "foo"

At this point, subsetting removes attributes:

> vec[1:5]
[1] 1 2 3 4 5

If we add a method [.foo we can preserve the attributes:

`[.foo` <- function(x, i, ...) {
    attrs <- attributes(x)
    out <- unclass(x)
    out <- out[i]
    attributes(out) <- attrs
    out
}

Now the desired behaviour is preserved

> vec[1:5]
[1] 1 2 3 4 5
attr(,"someattr")
[1] "Hello World"
attr(,"class")
[1] "foo"

And the answer to the bonus question:

From ?"[" in the details section:

Subsetting (except by an empty index) will drop all attributes except names, dim and dimnames.

like image 185
Gavin Simpson Avatar answered Nov 15 '22 22:11

Gavin Simpson