2014-05-21 71 views
2

让人不解的访问访问的对象的“伪缝隙”列表的元素。包含与名称的列表子类S4类:按名称

这是成功使用2出4接近于一个可以试试:

setClass("TempA", contains="list") 
A = new("TempA", list(a=1,b=2)) 
A 

只是打印不显示列表的名称。

## An object of class "TempA" 
## [[1]] 
## [1] 1 
## 
## [[2]] 
## [1] 2 

不过,您可以按名称提取元素。

A[["b"]] 
## [1] 2 

而names()提取名称。

names(A) 
## [1] "a" "b" 

但是在伪槽中没有名字。

[email protected] 
## [[1]] 
## [1] 1 
## 
## [[2]] 
## [1] 2 

那么名称隐藏在哪里,如果不是在伪槽本身?

情节复杂。我的目标是子类化(添加一些插槽;这里没有显示)。 但是,如果我们继承,即使上述两个成功的方法现在失败。名单的名字显然没有。

setClass("TempB", contains="TempA") 
B = new("TempB", list(a=1,b=2)) 
names(B) ## no names. 
## NULL 
B[["b"]] ## NULL 
## NULL 

下面是一种不同的方法。这是否做到了?不。

B2 = new("TempB", new("TempA", list(a=1,b=2))) 
B2[["a"]] # NULL 
## NULL 
names(B2) # NULL 
## NULL 
names(as(B2, "TempA")) ## still no dice 
## NULL 

总之,当伪缝隙是命名列表,试图查看或使用这些名称是成功的只有2个4显而易见的方法,子类后零出4。解决这个问题不是问题;这很容易。 (尽管我想知道如何使用名称为TempB对象编写访问器),我只是想了解。

回答

2

S4实现时隙作为属性,而列表元件R商店名称作为列表上的属性。因此存在冲突,在?Classes中提到。在“解决方案”是创建一个类与“名”插槽

A = setClass("A", representation("list", names="character")) 

,但是这也需要姓名的明确管理,例如,

setMethod("[", c("A", "ANY", "missing", "missing"), 
    function(x, i, j, ..., drop=TRUE) 
{ 
    initialize(x, [email protected][i], names=names(x)[i], ...) 
}) 

通往

> a = A(list(a=1, b=2)) 
> a[2:1] 
An object of class "A" 
[[1]] 
[1] 2 

[[2]] 
[1] 1 

Slot "names": 
[1] "b" "a" 

但也明显不完整

> a[20] 
An object of class "A" 
[[1]] 
NULL 

Slot "names": 
[1] NA 
0

啊,马丁,你的回答让我发现了一些令我惊讶的发现!谢谢。指点我看看实例的attributes是关键。我错过了课程中的那一段。

以下内容显示,该列表中的.Data插槽转移到该实例本身的属性names

attributes(A)$names 
## [1] "a" "b" 

那么,是不是所有的属性从.Data插槽的实例移动?确实是的!

tempList = list(a=3, b=4) 
attributes(tempList)$dummy = "dummy" 
E = new("TempA", tempList) 
attributes(E)$names 
## $names 
## [1] "a" "b" 
## 
attributes(E)$dummy 
## $dummy 
## [1] "dummy" 
attributes([email protected]) 
## NULL 

那么,不是所有的属性。原始问题中上述对象B2的结果显示,如果.Data项本身是一个实例,则其属性不会转移到包含的实例。

这仍然留下了一个问题。当然,你不想传输$class属性!但为什么不转移所有其他属性?