2012-02-28 13 views
10

Digamos que tienen un vector donde he establecido algunos atributos:Atributos Mantener en vectores

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

Cuando subconjunto del vector, los atributos se dejan caer. Por ejemplo:

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

¿Hay alguna forma de subconjuntos y persistir atributos sin tener que guardarlos en otro objeto temporal?

Prima: ¿Dónde encontraríamos documentación deeste comportamiento?

Respuesta

11

Escribiría un método para [ o subset() (dependiendo de cómo esté subconjunto) y lo organizaría para conservar los atributos. Eso necesitaría un atributo "class" que también agrega a su vector para que se produzca el envío.

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

En este punto, subsetting elimina atributos:

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

Si añadimos un método [.foo podemos conservar los atributos:

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

Ahora el comportamiento deseado se conserva

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

Y la respuesta a la pregunta extra:

De ?"[" en la sección de detalles:

de subdivisión (excepto por un índice vacío) se reducirá todos los atributos excepto nombres, tenues y dimnames.

+0

Thx para la respuesta! Por cierto, para listas de subconjuntos se puede incluir antes de transferir atributos a out, 'if (! is.null (attrs $ names)) attrs $ names = names (x) [i]' a los nombres de las listas de subconjuntos también. De lo contrario, es probable que cause un error. –