12

オブジェクトとそのスロットの操作経験があるS4ので、特定のスロットとサブスロットにアクセスする方法を知っています。私が学びたいのunlistは、S3リストを分解する方法でオブジェクトを「スロット解除」する方法です。
私の当面の目標は、オブジェクトの要素の数を返す私のおもちゃの1つに対応するS4を用意することです。

lssize<-function(items){
            if (any(sapply(sapply(items,get),typeof)=='closure')){
        warning('Closures in list, will ignore.')
        items<-items[(sapply(sapply(bar,get),typeof)=='closure')!=TRUE]
    }
    sizes<-sapply(sapply(sapply(sapply(items,get,simplify=F), unlist,simplify=F), as.vector,simplify=F), length)
    return(sizes)
    }

(私のコードを公正に笑うことはありません:-))。スロットを一度に1つずつ抽出して変換する再帰ルーチンを作成する必要がないことを望んでいます。

編集:object.sizeバイトカウントが返されることはわかっています。私がここで求めているものではありません。

4

1 に答える 1

9

(これは、以前の削除された回答に近くなるように改訂され、に依存するのではなく、を使用slotNameします)。インスタンスがS4オブジェクトであるかどうかをテストする関数を記述できます。その場合、すべてのスロットをリストとして抽出し、再帰します。slotattributes

f = function(x) {
    if (isS4(x)) {
        nms <- slotNames(x)
        names(nms) <- nms
        lapply(lapply(nms, slot, object=x), f)
    } else x
}

その後

A = setClass("A", representation(x="numeric"))
B = setClass("B", representation(a="A", b="numeric"))
f(B())

私たちが望むどんな目的にも使用できる、昔ながらのリストにたどり着くために。

$a
$a$x
numeric(0)

$a$class
[1] "A"
attr(,"package")
[1] ".GlobalEnv"


$b
numeric(0)

$class
[1] "B"
attr(,"package")
[1] ".GlobalEnv"

fたとえば、NULL値またはS3クラスから作成されたS4クラスを処理するために拡張する必要がある場合がありますsetOldClass。のコードvalidObjectは、より包括的なトラバーサルを探す場所の私の選択です。

一般化は、の線に沿って、訪問者を作るかもしれません

visitLeavesWith <-
    function(object, FUN, ...)
{
    f = function(x) {
        if (isS4(x)) {
            slots <- setNames(slotNames(x), slotNames(x))
            lapply(lapply(slots, slot, object=x), f)
        } else FUN(x, ...)
    }
    f(object)
}

例えば、

visitLeavesWith(B(), length)
于 2013-02-11T01:25:59.357 に答える