2014-05-21 96 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屬性!但爲什麼不轉移所有其他屬性?