Apparently, indexing a list with attributes returns a list without the attributes.
> l <- list(a=1:3, b=7)
> attr(l, \'x\') <- 67
> l
$a
[1] 1
Use the sticky
package. It was designed exactly for this purpose. (Full Disclosure: I am the package author.) It's simple to use, just call sticky()
on your vector/list/etc. For example:
> l <- list(a=1:3, b=7)
> attr(l, 'x') <- 67
> l <- sticky(l)
> attr(l,'x')
> [1] 67
>
> class(l)
> [1] "sticky" "list"
Here is such a subset function. Note that it is important to not try to overwrite the 'names' attribute.
subset.with.attributes <- function(X, ...) {
l <- X[...]
attr.names <- names(attributes(X))
attr.names <- attr.names[attr.names != 'names']
attributes(l)[attr.names] <- attributes(X)[attr.names]
return(l)
}
> subset.with.attributes(l, c('a','b'))
$a
[1] 1 2 3
$b
[1] 7
attr(,"x")
[1] 67
Trying to simply assign the attributes will result in the subset failing if it actually does any subsetting.
> subset.with.attributes(l, c('b'))
$b
[1] 7
attr(,"x")
[1] 67