2017-01-11 1 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]])과 같은 특정 요소에서 정보를 추출 할 수는 있지만 일반화 된 솔루션을 찾고 있습니다. 문제는 "깊이"에 관계없이 각 요소에 대해 동일한 정보를 추출하고자한다는 것입니다.

감사합니다. purrr 패키지는 여기에 도움이 될 수있는 것처럼

+1

몇 가지 샘플 데이터가 없으면 언급하기가 어렵지만 rapply를 살펴 보셨습니까? –

+0

샘플 데이터는 해당 패키지의 예제에서 쉽게 얻을 수 있습니다. 실제 질문은 슬롯이 – davidski

+0

에 관심이있는 @dmp입니다. 몇 가지 유용한 기능을 알려주기 위해 노력하고 있었지만 분명한 이유가 없기 때문에 답을 얻고 있습니다. 만약 당신이 어떤 종류의 슬롯을 정확하게 게시하고 싶다면, 나는 당신이 원하는 것을 추출하는 이러한 함수를 사용하여 코드를 기꺼이 게시 할 것입니다. – davidski

답변

-1

는 것, 특히 기능 flatten, transpose, map/at_depth 같은 - 당신은 쉽게 중첩 목록에서 물건을 추출 할 수 있습니다 입력으로 문자 벡터와 결합. 예를 들어 별도로 필요한 "추출기"기능을 기록한 다음 목록에 모두 저장하고 invoke (또는 purrr)을 객체와 함께 단독 인수로 사용하거나 invoke_map 같은 객체에서 사용할 수 있습니다.

편집 여기
는 하나 또는 여러 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

관련 문제