我正试图从bib文件中获取特定标签的值.每当我尝试和我们entry["bibtype"]
或entry[["bibtype"]]
我得到一个错误,但entry$bibtype
工作正常.
entry<-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/")
# the first two fail
entry["bibtype"]
entry[["bibtype"]]
entry$bibtype
foo <- list("bar" = "baz")
#all of these work
foo["bar"]
foo[["bar"]]
foo$bar
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
Error in switch(attr(paper, "bibtype"), Article = formatArticle(paper), :
EXPR must be a length 1 vector
Run Code Online (Sandbox Code Playgroud)
有人解决了这个吗?无论如何强迫bibentries接受这个?
TL;博士
"bibtype"
不是"bibentry"
对象中的命名组件,而是作为属性实现.如果$
这些对象是选中的"东西",那么这些对象的方法就是一个特殊情况来访问属性,而[
和[[
方法没有这个"特征".
使用rref
如下定义
> attributes(unclass(rref)[[1]])$bibtype
[1] "Manual"
> attr(unclass(rref)[[1]], "bibtype")
[1] "Manual"
Run Code Online (Sandbox Code Playgroud)
请参阅长版本以获得更广泛的展示
您需要对象的属性,但这些属性似乎无法通过常用方法使用,例如使用以下示例?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/")
Run Code Online (Sandbox Code Playgroud)
我们注意到"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"
Run Code Online (Sandbox Code Playgroud)
但是我们无法访问该属性
> attr(rref, "bibtype")
NULL
> attr(rref[[1]], "bibtype")
NULL
Run Code Online (Sandbox Code Playgroud)
第一个失败是因为就R而言,类的对象"bibentry"
在R中实现的方式(或者更确切地说应用于它们的方法)attributes()
也attr()
看不到这个特定的属性.唯一可见的属性是:
> attributes(rref)
$class
[1] "bibentry"
> attributes(rref[1])
$class
[1] "bibentry"
Run Code Online (Sandbox Code Playgroud)
如果我们unclass()
rref
,那么我们需要意识到对象是一个包含bibentries的组件的列表.在这种情况下,它rref
是一个包含单个组件的列表,它是类"bibentry"的对象,它是7个组件的列表.
一个天真的人会认为你可以这样做:
attr(rref[[1]], "bibtype")
Run Code Online (Sandbox Code Playgroud)
这将从第一个"bibentry"
对象rref
(只有一个)中获取并查找其中的属性.这不起作用:
> attributes(rref[[1]])
$class
[1] "bibentry"
Run Code Online (Sandbox Code Playgroud)
因为对象的方法[
和[[
实现方式"bibentry"
:
> utils:::`[[.bibentry`
function (x, i)
{
rval <- unclass(x)[i]
class(rval) <- class(x)
rval
}
<bytecode: 0x1a75938>
<environment: namespace:utils>
Run Code Online (Sandbox Code Playgroud)
[单一[
方法以完全相同的方式实现.]这意味着你可以做这样的愚蠢的事情:
> 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/>.
Run Code Online (Sandbox Code Playgroud)
这没有任何意义,但[[1]]
每次只是指同一个对象.我不知道这是否是故意的; ?bibentry
具有
Note:
The bibentry functionality is still experimental.
Run Code Online (Sandbox Code Playgroud)
但它不是最理想的.
现在,您需要遵循实现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"
Run Code Online (Sandbox Code Playgroud)
对比该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>
Run Code Online (Sandbox Code Playgroud)
此方法专门用于处理属性.这在R中看起来似乎有些非标准行为.这就解释了原因
> rref$bibtype
[1] "Manual"
Run Code Online (Sandbox Code Playgroud)
但是(天真的)基本相同
> str(rref[["bibtype"]])
Class 'bibentry' hidden list of 1
$ : NULL
Run Code Online (Sandbox Code Playgroud)
失败,因为没有在未"bibtype"
显示的列表中命名的组件,因此返回NULL
组件,而在打印时发生错误:
> foo <- rref[["bibtype"]]
> foo
Error in switch(attr(paper, "bibtype"), Article = formatArticle(paper), :
EXPR must be a length 1 vector
Run Code Online (Sandbox Code Playgroud)