tl; dr
"bibtype"
не является именованным компонентом в объекте "bibentry"
, вместо этого он реализован как атрибут.Метод $
для этих объектов создал особый случай для доступа к атрибуту, если он выбран как "вещь", тогда как методы [
и [[
не имеют этой "функции".
Использование rref
, как определено ниже
> attributes(unclass(rref)[[1]])$bibtype
[1] "Manual"
> attr(unclass(rref)[[1]], "bibtype")
[1] "Manual"
См. Расширенную версию для более широкой экспозиции
Вы хотите атрибуты объекта, но они не доступны для использования черезобычные методы, например, используя пример из ?bibentry
:
## R reference
rref <- bibentry(bibtype = "Manual",
title = "R: A Language and Environment for Statistical Computing",
author = person("R Development Core Team"),
organization = "R Foundation for Statistical Computing",
address = "Vienna, Austria",
year = 2010,
isbn = "3-900051-07-0",
url = "http://www.R-project.org/")
, мы отмечаем атрибут "bibtype"
в выводе из str()
> str(rref)
Class 'bibentry' hidden list of 1
$ :List of 7
..$ title : chr "R: A Language and Environment for Statistical Computing"
..$ author :Class 'person' hidden list of 1
.. ..$ :List of 5
.. .. ..$ given : chr "R Development Core Team"
.. .. ..$ family : NULL
.. .. ..$ role : NULL
.. .. ..$ email : NULL
.. .. ..$ comment: NULL
..$ organization: chr "R Foundation for Statistical Computing"
..$ address : chr "Vienna, Austria"
..$ year : chr "2010"
..$ isbn : chr "3-900051-07-0"
..$ url : chr "http://www.R-project.org/"
..- attr(*, "bibtype")= chr "Manual"
, но мы не 'не может получить доступ к этому атрибуту
> attr(rref, "bibtype")
NULL
> attr(rref[[1]], "bibtype")
NULL
Первый сбой, потому что, что касается R, то, как объекты класса "bibentry"
реализованы в R (или, скорее, к ним применены методы) attributes()
, ниattr()
может видеть этот конкретный атрибут.Единственные видимые атрибуты:
> attributes(rref)
$class
[1] "bibentry"
> attributes(rref[1])
$class
[1] "bibentry"
Если мы unclass()
rref
, то нам нужно понять, что объект представляет собой список с таким же количеством компонентов, что и двукратные.В этом случае rref
- это список с одним компонентом, который является объектом класса "bibentry", который представляет собой список из 7 компонентов.
Один наивно предположил бы, что вы могли бы сделать это:
attr(rref[[1]], "bibtype")
, который берет первый "bibentry"
объект из rref
(есть только один) и ищет атрибуты для этого.Это не работает:
> attributes(rref[[1]])
$class
[1] "bibentry"
из-за способа реализации методов для [
и [[
для "bibentry"
объектов:
> utils:::`[[.bibentry`
function (x, i)
{
rval <- unclass(x)[i]
class(rval) <- class(x)
rval
}
<bytecode: 0x1a75938>
<environment: namespace:utils>
[Single [
метод реализован точно так же.] Это означает, что вы можете делать глупые вещи, как это:
> rref[[1]][[1]][[1]][[1]]
R Development Core Team (2010). _R: A Language and Environment for
Statistical Computing_. R Foundation for Statistical Computing, Vienna,
Austria. ISBN 3-900051-07-0, <URL: http://www.R-project.org/>.
, который не имеет никакого смысла, но все [[1]]
просто ссылаются на один и тот же объект,каждый раз.Я не знаю, намеренно это или нет;?bibentry
имеет
Note:
The bibentry functionality is still experimental.
, но это неоптимально.
На данный момент вам необходимо проследить реализацию в utils:::`[.bibentry`
и unclass()
объекта, а затем начать подмножество и получить доступ кАтрибуты:
> attributes(unclass(rref)[[1]])
$names
[1] "title" "author" "organization" "address" "year"
[6] "isbn" "url"
$bibtype
[1] "Manual"
> attributes(unclass(rref)[[1]])$bibtype
[1] "Manual"
> attr(unclass(rref)[[1]], "bibtype")
[1] "Manual"
Сравните реализацию метода utils:::`$.bibentry`
с реализацией для utils:::`[[.bibentry`
:
> utils:::`$.bibentry`
function (x, name)
{
is_attribute <- name %in% bibentry_attribute_names
rval <- if (is_attribute)
lapply(unclass(x), attr, name)
else lapply(unclass(x), "[[", name)
if (length(rval) == 1L)
rval <- rval[[1L]]
rval
}
<bytecode: 0x1b0fd70>
<environment: namespace:utils>
Этот метод был специально разработан для работы с атрибутами.Это все кажется несколько нестандартным поведением в R. Это объясняет, почему
> rref$bibtype
[1] "Manual"
работает, но (наивно) по существу эквивалентно
> str(rref[["bibtype"]])
Class 'bibentry' hidden list of 1
$ : NULL
терпит неудачу, потому что нет компонент с именем "bibtype"
в неклассифицированном списке, поэтому возвращается компонент NULL
, тогда как при печати возникает ошибка:
> foo <- rref[["bibtype"]]
> foo
Error in switch(attr(paper, "bibtype"), Article = formatArticle(paper), :
EXPR must be a length 1 vector