2012-11-17 2 views
4

По-видимому, индексирование списка с атрибутами возвращает список без атрибутов.операция индексирования удаляет атрибуты

> l <- list(a=1:3, b=7) 
> attr(l, 'x') <- 67 
> l 
$a 
[1] 1 2 3 

$b 
[1] 7 

attr(,"x") 
[1] 67 
> l[c('a','b')] 
$a 
[1] 1 2 3 

$b 
[1] 7 

Атрибуты исчезли. Возможно ли индексировать список при сохранении его атрибутов?

+3

Это документированное поведение (см. '?" ["'). Вы можете написать свою собственную функцию подмножества (или определить класс и метод индексирования для нее). – Roland

+0

@Roland Да, это задокументировано. Похоже, единственные варианты - это те, которые вы упомянули. –

+0

Липкие пакеты делают это. – ctbrown

ответ

4

Вот такая функция подмножества. Обратите внимание, что важно не пытаться перезаписать атрибут «names».

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 

Попытка просто присвоить атрибуты приведет к сбою подмножества, если на самом деле это подмножество.

> subset.with.attributes(l, c('b')) 
$b 
[1] 7 

attr(,"x") 
[1] 67 
1

Используйте пакет sticky. Он был разработан именно для этой цели. (Полное раскрытие: я автор пакета.) Прост в использовании, просто позвоните sticky() на свой вектор/список/и т. Д. Например:

> l <- list(a=1:3, b=7) 
> attr(l, 'x') <- 67  
> l <- sticky(l) 
> attr(l,'x') 
> [1] 67 
> 
> class(l) 
> [1] "sticky" "list" 
Смежные вопросы