2017-01-11 13 views
-1

私は非常に複雑なS4オブジェクト(lavaanモデルの出力)を持っています。このオブジェクトは、スロット内のスロット内にスロットを持ち、最も深い各スロットの最も深いレベルに変数($)を持っています。このオブジェクト内のすべての要素のobject.size(および可能であればlengthdimのような他の関数とオブジェクト名)を抽出して格納するには、同じクラスの別のオブジェクトと比較できるようにするにはどうすればよいですか?複雑なオブジェクトの要素を要約する方法は?

私はstr(obj)とからの出力を保存して、私が欲しい情報を抽出するために、出力を操作しようとしたが、非常に面倒であることが判明回しています。名前をループすることも同様に困難です。オブジェクトをリストに「平坦化」する方法はありますか?誰もが各スロットを繰り返し掘り下げると考えることができる再帰関数はありますか?ここを編集

は、理想的解決策は、特定のオブジェクトのクラスに依存すべきではないとクラス全体で仕事ができるのに、私は上記参照lavaanパッケージを使用して、例を示します

library(lavaan) 
model <- ' 
    # measurement model 
    ind60 =~ x1 + x2 + x3 
    dem60 =~ y1 + y2 + y3 + y4 
    dem65 =~ y5 + y6 + y7 + y8 
    # regressions 
    dem60 ~ ind60 
    dem65 ~ ind60 + dem60 
    # residual correlations 
    y1 ~~ y5 
    y2 ~~ y4 + y6 
    y3 ~~ y7 
    y4 ~~ y8 
    y6 ~~ y8 
'   
fit <- sem(model, data=PoliticalDemocracy) 

オブジェクトfitには、内部に多数のスロットとオブジェクトが含まれています。私は、もちろん、object.size([email protected]@X[[1]])のような特定の要素から情報を抽出することができますが、私は一般化された解決策を探しています。課題は、「深さ」に関係なく、各要素について同じ情報を抽出したいということです。

ありがとうございます!あなたが簡単に深くネストされたリストからのものを抽出することができ、入力として文字ベクトルと組み合わせる -

+1

サンプルデータがないとコメントするのは難しいですが、あなたはラップリーを見ましたか? –

+0

サンプルデータは、対応するパッケージのサンプルから簡単に入手できます。実際の質問は、どのスロットが@DMPに興味があるのですか? – davidski

+0

便利な機能を紹介しようとしていましたが、私の答えは明白な理由なしに下降しています。あなたがオブジェクトから興味を持っているスロットを正確に投稿することができれば、私はあなたが望むものを抽出するこれらの関数を使っていくつかのコードを投稿しています。 – davidski

答えて

-1

purrrパッケージのように思えるが、ここで助けにflattentransposemap/at_depthのような特に機能かもしれません。たとえば、分離して必要な「抽出」機能を書き留めて、すべてをリストに格納し、そのオブジェクトにinvoke(またはpurrr)を単独の引数として、またはinvoke_mapをそのようなオブジェクトに使用することができます。

編集
ここでは、1つまたは多くのlavaanオブジェクトからobject.size([email protected]@X[[1]])を抽出するのに役立ついくつかのコードです。あなたが興味を持っているスロットは実際にはおそらく異なる深さにあるので、簡単な一般的な解決法はないと私は推測します。
アイデアは、あなたが興味を持っている正確な要素を知っているということです。単一の/複数のそのようなオブジェクトを操作するヘルパー関数をコード化するのはかなり簡単です。私が上で述べた機能は、これを達成するためのフレンドリーなショートカットを提供します。
もし私がさらに助けになることができたら教えてください。

library("lavaan") 
    library("tidyverse") 

    model <- ' 
    # measurement model 
    ind60 =~ x1 + x2 + x3 
    dem60 =~ y1 + y2 + y3 + y4 
    dem65 =~ y5 + y6 + y7 + y8 
    # regressions 
    dem60 ~ ind60 
    dem65 ~ ind60 + dem60 
    # residual correlations 
    y1 ~~ y5 
    y2 ~~ y4 + y6 
    y3 ~~ y7 
    y4 ~~ y8 
    y6 ~~ y8 
    '   

    # say you have 3 different models 
    fit1 <- sem(model, data=PoliticalDemocracy) 
    fit2 <- sem(model, data=PoliticalDemocracy) 
    fit3 <- sem(model, data=PoliticalDemocracy) 

    # S4 objects have function slot() function for accessing so 
    object.size([email protected]@X[[1]]) 
    # becomes 
    slot(slot(fit, "Data"), "X")[[1]] 

    # since fit is an S4 object - you have to wrap it up 
    # in a list to manipulate it easier. 
    # above code becomes : 
    list(fit1) %>% 
    map(~ slot(., "Data")) %>% 
    map(~ slot(., "X")) %>% 
    flatten %>% 
    map(object.size) 

    # wrap up the above code in a helper function ... 
    extr_obj_size <- function(lavaan_fit) { 
    list(lavaan_fit) %>% 
     map(~ slot(., "Data")) %>% 
     map(~ slot(., "X")) %>% 
     map(object.size) 
    } 

    extr_obj_size(fit1) 

    # which you can further wrap up in a function that operates 
    # on a vector of such objects 
    extr_multiple_obj_size <- function(vec_lavaan_fits) { 
    vec_lavaan_fits %>% 
     map(extr_obj_size) %>% 
     flatten 

    } 

    c(fit,fit2,fit3) %>% extr_multiple_obj_size 

EDIT2

私はどのように役立つ次のコードは、一般にだろうかわからないが、私ははあなたが興味のあるスロットの名前を知っていることを考えると、何かをごちゃ混ぜ - 深さ1と2で確認し、対応する値を返します。

fit <- sem(model, data=PoliticalDemocracy) 
slot_of_interest <- "eq.constraints" 

# slot names at depth 1 
depth1 <- names(getSlots("lavaan")) 
# slot names at depth 2 
depth2 <- depth1 %>% map(~ slotNames(slot(fit,.))) 

# helper fun to check if a slot name of interest is inside a slot 
in_slot <- function(x) slot_of_interest %in% x 

# so if its at depth 1 - then just map slot()-function with that name 
if (slot_of_interest %in% depth1) { 
    list(fit1) %>% map(~slot(., slot_of_interest)) 
} else { 
    # otherwise you would need to detect at which index at depth2 does this name appear 
    index1 <- depth2 %>% detect_index(in_slot) 
    # and map first the slot-name at that index - then the corresponding slot of interest 
    list(fit1) %>% map(~ slot(., depth1[index1])) %>% map(~ slot(., slot_of_interest)) 
} 
+1

downvote?なぜ私の答えを拡張するのに役立つかという少なくともコメント。私が助けようとしている – davidski

関連する問題